interspire 0.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +9 -0
- data/README.md +1 -1
- data/interspire.gemspec +2 -1
- data/lib/interspire.rb +1 -1
- data/lib/interspire/api.rb +72 -15
- data/spec/fixtures/update_subscriber_custom_field.xml +5 -0
- data/spec/interspire/api_spec.rb +14 -0
- metadata +53 -14
data/.travis.yml
ADDED
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Interspire
|
1
|
+
# Interspire [![Build Status](https://travis-ci.org/Oshuma/interspire.png?branch=master)](https://travis-ci.org/Oshuma/interspire)
|
2
2
|
|
3
3
|
Ruby library for the {http://www.interspire.com/ Interspire} API ({https://www.interspire.com/support/kb/questions/1224/Email+Marketer+XML+API+Documentation pdf}).
|
4
4
|
|
data/interspire.gemspec
CHANGED
@@ -17,8 +17,9 @@ Gem::Specification.new do |gem|
|
|
17
17
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
18
|
gem.require_paths = ["lib"]
|
19
19
|
|
20
|
-
gem.add_runtime_dependency
|
20
|
+
gem.add_runtime_dependency('nokogiri', "~> 1.6")
|
21
21
|
|
22
|
+
gem.add_development_dependency 'rake'
|
22
23
|
gem.add_development_dependency 'rspec'
|
23
24
|
gem.add_development_dependency 'webmock'
|
24
25
|
gem.add_development_dependency 'yard'
|
data/lib/interspire.rb
CHANGED
data/lib/interspire/api.rb
CHANGED
@@ -1,5 +1,8 @@
|
|
1
|
-
|
2
|
-
require '
|
1
|
+
begin
|
2
|
+
require 'net/http'
|
3
|
+
require 'nokogiri'
|
4
|
+
rescue LoadError
|
5
|
+
end
|
3
6
|
|
4
7
|
module Interspire
|
5
8
|
# TODO: The methods expecting a list ID should also accept a ContactList object.
|
@@ -20,9 +23,12 @@ module Interspire
|
|
20
23
|
# @param email [String] The subscriber's email address.
|
21
24
|
# @param confirmed [boolean] (optional) +true+ if the subscriber should be set as confirmed; defaults to +false+.
|
22
25
|
# @param format [String] (optional) The email format; either +html+ or +text+; defaults to +html+.
|
26
|
+
# @param custom_fields [Hash] (optional) Any custom fields for the subscriber (e.g. {1 => 'Banana', 2 => 'Hamster'})
|
23
27
|
#
|
24
28
|
# @return [Integer] Returns the subscriber's ID upon success.
|
25
|
-
def add_subscriber(list_id, email, confirmed = false, format = 'html')
|
29
|
+
def add_subscriber(list_id, email, confirmed = false, format = 'html', custom_fields = {})
|
30
|
+
custom_fields_xml = custom_fields.map { |key, value| "<item><fieldid>#{key}</fieldid><value>#{value}</value></item>" }.join
|
31
|
+
|
26
32
|
xml = %Q[
|
27
33
|
<xmlrequest>
|
28
34
|
<username>#{@user}</username>
|
@@ -34,6 +40,9 @@ module Interspire
|
|
34
40
|
<mailinglist>#{list_id}</mailinglist>
|
35
41
|
<format>#{format}</format>
|
36
42
|
<confirmed>#{confirmed}</confirmed>
|
43
|
+
<customfields>
|
44
|
+
#{custom_fields_xml}
|
45
|
+
</customfields>
|
37
46
|
</details>
|
38
47
|
</xmlrequest>
|
39
48
|
]
|
@@ -165,29 +174,60 @@ module Interspire
|
|
165
174
|
#
|
166
175
|
# @return [boolean] +true+ or +false+ if the +email+ is on the given contact list.
|
167
176
|
def in_contact_list?(list_id, email)
|
177
|
+
response = check_contact_list(list_id, email)
|
178
|
+
|
179
|
+
if success?(response)
|
180
|
+
# The 'data' element will contain the subscriber ID.
|
181
|
+
! response.xpath('response/data').first.content.empty?
|
182
|
+
else
|
183
|
+
false
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
# @param list_id [Integer] The ID of the contact list.
|
188
|
+
# @param email [String] The subscriber's email address.
|
189
|
+
#
|
190
|
+
# @return [Integer] Returns the subscriber's ID upon success.
|
191
|
+
def get_subscriber_id(list_id, email)
|
192
|
+
response = check_contact_list(list_id, email)
|
193
|
+
|
194
|
+
if success?(response)
|
195
|
+
response.xpath('response/data').first.content.to_i
|
196
|
+
else
|
197
|
+
error!(response)
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
# This is an undocumented API function. Refer to the 'xml_updatesubscriber.php' attachment
|
202
|
+
# on this page: https://www.interspire.com/support/kb/questions/1217/Email+Marketer+XML+API+usage+and+examples
|
203
|
+
#
|
204
|
+
# @param subscriber_id [Integer] The ID of the subscriber.
|
205
|
+
# @param field_id [Integer] The ID of the custom field
|
206
|
+
# @param data [String] The data of the field
|
207
|
+
#
|
208
|
+
# @return [boolean] Returns +true+ if the field was updated.
|
209
|
+
def update_subscriber_custom_field(subscriber_id, field_id, data)
|
168
210
|
xml = %Q[
|
169
211
|
<xmlrequest>
|
170
|
-
<username>#{@
|
171
|
-
<usertoken>#{@
|
212
|
+
<username>#{@username}</username>
|
213
|
+
<usertoken>#{@usertoken}</usertoken>
|
172
214
|
<requesttype>subscribers</requesttype>
|
173
|
-
<requestmethod>
|
215
|
+
<requestmethod>SaveSubscriberCustomField</requestmethod>
|
174
216
|
<details>
|
175
|
-
<
|
176
|
-
|
217
|
+
<subscriberids>
|
218
|
+
<id>#{subscriber_id}</id>
|
219
|
+
</subscriberids>
|
220
|
+
<fieldid>#{field_id}</fieldid>
|
221
|
+
<data>#{data}</data>
|
177
222
|
</details>
|
178
223
|
</xmlrequest>
|
179
224
|
]
|
180
225
|
|
181
226
|
response = get_response(xml)
|
182
|
-
|
183
|
-
if success?(response)
|
184
|
-
# The 'data' element will contain the subscriber ID.
|
185
|
-
! response.xpath('response/data').first.content.empty?
|
186
|
-
else
|
187
|
-
false
|
188
|
-
end
|
227
|
+
success?(response)
|
189
228
|
end
|
190
229
|
|
230
|
+
|
191
231
|
private
|
192
232
|
|
193
233
|
# @param xml [String] A String containing the XML request.
|
@@ -219,5 +259,22 @@ module Interspire
|
|
219
259
|
raise InterspireException, "#{type}: #{error.empty? ? 'No error message given.' : error}"
|
220
260
|
end
|
221
261
|
|
262
|
+
def check_contact_list(list_id, email)
|
263
|
+
xml = %Q[
|
264
|
+
<xmlrequest>
|
265
|
+
<username>#{@user}</username>
|
266
|
+
<usertoken>#{@token}</usertoken>
|
267
|
+
<requesttype>subscribers</requesttype>
|
268
|
+
<requestmethod>IsSubscriberOnList</requestmethod>
|
269
|
+
<details>
|
270
|
+
<emailaddress>#{email}</emailaddress>
|
271
|
+
<listids>#{list_id}</listids>
|
272
|
+
</details>
|
273
|
+
</xmlrequest>
|
274
|
+
]
|
275
|
+
|
276
|
+
get_response(xml)
|
277
|
+
end
|
278
|
+
|
222
279
|
end
|
223
280
|
end
|
data/spec/interspire/api_spec.rb
CHANGED
@@ -80,6 +80,20 @@ describe Interspire::API do
|
|
80
80
|
stub_request(:post, @api_url).to_return(:body => fixture("not_in_contact_list.xml"))
|
81
81
|
@api.in_contact_list?(1, 'foo@example.com').should_not be_true
|
82
82
|
end
|
83
|
+
|
84
|
+
it 'should get subscriber ID' do
|
85
|
+
stub_request(:post, @api_url).to_return(:body => fixture("in_contact_list.xml"))
|
86
|
+
subscriber_id = @api.get_subscriber_id(1, 'foo@example.com') # '1' is the (fake) contact list ID.
|
87
|
+
subscriber_id.should be_a(Integer)
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'should update the subscriber custom field' do
|
91
|
+
stub_request(:post, @api_url).to_return(:body => fixture("update_subscriber_custom_field.xml"))
|
92
|
+
# '1' is the (fake) contact ID
|
93
|
+
# '2' is the (fake) custom field ID
|
94
|
+
response = @api.update_subscriber_custom_field(1, 2, "Jane")
|
95
|
+
response.should be_true
|
96
|
+
end
|
83
97
|
end
|
84
98
|
|
85
99
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: interspire
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,22 +9,43 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-09-06 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: nokogiri
|
16
|
-
requirement:
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '1.6'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.6'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rake
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
17
33
|
none: false
|
18
34
|
requirements:
|
19
35
|
- - ! '>='
|
20
36
|
- !ruby/object:Gem::Version
|
21
37
|
version: '0'
|
22
|
-
type: :
|
38
|
+
type: :development
|
23
39
|
prerelease: false
|
24
|
-
version_requirements:
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
25
46
|
- !ruby/object:Gem::Dependency
|
26
47
|
name: rspec
|
27
|
-
requirement:
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
28
49
|
none: false
|
29
50
|
requirements:
|
30
51
|
- - ! '>='
|
@@ -32,10 +53,15 @@ dependencies:
|
|
32
53
|
version: '0'
|
33
54
|
type: :development
|
34
55
|
prerelease: false
|
35
|
-
version_requirements:
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
36
62
|
- !ruby/object:Gem::Dependency
|
37
63
|
name: webmock
|
38
|
-
requirement:
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
39
65
|
none: false
|
40
66
|
requirements:
|
41
67
|
- - ! '>='
|
@@ -43,10 +69,15 @@ dependencies:
|
|
43
69
|
version: '0'
|
44
70
|
type: :development
|
45
71
|
prerelease: false
|
46
|
-
version_requirements:
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
47
78
|
- !ruby/object:Gem::Dependency
|
48
79
|
name: yard
|
49
|
-
requirement:
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
50
81
|
none: false
|
51
82
|
requirements:
|
52
83
|
- - ! '>='
|
@@ -54,7 +85,12 @@ dependencies:
|
|
54
85
|
version: '0'
|
55
86
|
type: :development
|
56
87
|
prerelease: false
|
57
|
-
version_requirements:
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
58
94
|
description: Ruby library for the Interspire API.
|
59
95
|
email:
|
60
96
|
- oshuma@gmail.com
|
@@ -64,6 +100,7 @@ extensions: []
|
|
64
100
|
extra_rdoc_files: []
|
65
101
|
files:
|
66
102
|
- .gitignore
|
103
|
+
- .travis.yml
|
67
104
|
- Gemfile
|
68
105
|
- LICENSE.txt
|
69
106
|
- README.md
|
@@ -83,6 +120,7 @@ files:
|
|
83
120
|
- spec/fixtures/not_authenticated.xml
|
84
121
|
- spec/fixtures/not_in_contact_list.xml
|
85
122
|
- spec/fixtures/subscribers.xml
|
123
|
+
- spec/fixtures/update_subscriber_custom_field.xml
|
86
124
|
- spec/interspire/api_spec.rb
|
87
125
|
- spec/interspire/contact_list_spec.rb
|
88
126
|
- spec/spec_helper.rb
|
@@ -100,7 +138,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
100
138
|
version: '0'
|
101
139
|
segments:
|
102
140
|
- 0
|
103
|
-
hash:
|
141
|
+
hash: -3473573730335399156
|
104
142
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
105
143
|
none: false
|
106
144
|
requirements:
|
@@ -109,10 +147,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
109
147
|
version: '0'
|
110
148
|
segments:
|
111
149
|
- 0
|
112
|
-
hash:
|
150
|
+
hash: -3473573730335399156
|
113
151
|
requirements: []
|
114
152
|
rubyforge_project:
|
115
|
-
rubygems_version: 1.8.
|
153
|
+
rubygems_version: 1.8.23
|
116
154
|
signing_key:
|
117
155
|
specification_version: 3
|
118
156
|
summary: Ruby library for the Interspire API.
|
@@ -125,6 +163,7 @@ test_files:
|
|
125
163
|
- spec/fixtures/not_authenticated.xml
|
126
164
|
- spec/fixtures/not_in_contact_list.xml
|
127
165
|
- spec/fixtures/subscribers.xml
|
166
|
+
- spec/fixtures/update_subscriber_custom_field.xml
|
128
167
|
- spec/interspire/api_spec.rb
|
129
168
|
- spec/interspire/contact_list_spec.rb
|
130
169
|
- spec/spec_helper.rb
|