interspire 0.1.1 → 0.2.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.
@@ -0,0 +1,9 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.2
4
+ - 1.9.3
5
+ - 2.0.0
6
+
7
+ branches:
8
+ only:
9
+ - master
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
 
@@ -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 'nokogiri'
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'
@@ -4,5 +4,5 @@ require "interspire/interspire_exception"
4
4
  require "interspire/subscriber"
5
5
 
6
6
  module Interspire
7
- VERSION = "0.1.1"
7
+ VERSION = "0.2.0"
8
8
  end
@@ -1,5 +1,8 @@
1
- require 'net/http'
2
- require 'nokogiri'
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>#{@user}</username>
171
- <usertoken>#{@token}</usertoken>
212
+ <username>#{@username}</username>
213
+ <usertoken>#{@usertoken}</usertoken>
172
214
  <requesttype>subscribers</requesttype>
173
- <requestmethod>IsSubscriberOnList</requestmethod>
215
+ <requestmethod>SaveSubscriberCustomField</requestmethod>
174
216
  <details>
175
- <emailaddress>#{email}</emailaddress>
176
- <listids>#{list_id}</listids>
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
@@ -0,0 +1,5 @@
1
+ <?xml version="1.0" encoding="UTF-8" ?>
2
+ <response>
3
+ <status>SUCCESS</status>
4
+ <data>1</data>
5
+ </response>
@@ -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.1.1
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-02-20 00:00:00.000000000 Z
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: &80803630 !ruby/object:Gem::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: :runtime
38
+ type: :development
23
39
  prerelease: false
24
- version_requirements: *80803630
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: &80803380 !ruby/object:Gem::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: *80803380
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: &80803110 !ruby/object:Gem::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: *80803110
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: &80802850 !ruby/object:Gem::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: *80802850
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: 316495037
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: 316495037
150
+ hash: -3473573730335399156
113
151
  requirements: []
114
152
  rubyforge_project:
115
- rubygems_version: 1.8.10
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