exacto_subscriber 0.1.1
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/.document +5 -0
- data/.gitignore +22 -0
- data/.rvmrc +1 -0
- data/LICENSE +20 -0
- data/README.rdoc +23 -0
- data/Rakefile +93 -0
- data/VERSION +1 -0
- data/exacto.gemspec +79 -0
- data/exacto_subscriber.gemspec +81 -0
- data/lib/exacto_subscriber/base.rb +42 -0
- data/lib/exacto_subscriber/error.rb +16 -0
- data/lib/exacto_subscriber/subscriber.rb +117 -0
- data/lib/exacto_subscriber.rb +27 -0
- data/spec/cassettes/subscribers/find_by_email_and_list_id.yml +46 -0
- data/spec/cassettes/subscribers/subscribe.yml +136 -0
- data/spec/cassettes/subscribers/unsubscribe.yml +181 -0
- data/spec/exact_target_credentials.example.yml +3 -0
- data/spec/exacto/subcriber_spec.rb +73 -0
- data/spec/exacto_spec.rb +8 -0
- data/spec/spec.opts +2 -0
- data/spec/spec_helper.rb +36 -0
- metadata +186 -0
data/.document
ADDED
data/.gitignore
ADDED
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm ree@exacto
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Dan Pickett
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
= exacto_subscriber
|
2
|
+
|
3
|
+
A small library to handle Exact Target subscriptions
|
4
|
+
|
5
|
+
subscriber = Exacto::Subscriber.new("user@example.com",
|
6
|
+
:attributes => {:first__name => "John", :last__name => "Smith"})
|
7
|
+
|
8
|
+
subscriber.subsribe_to(1234) #1234 is the list id
|
9
|
+
subscriber.unsubscribe_from(1234)
|
10
|
+
|
11
|
+
== Note on Patches/Pull Requests
|
12
|
+
|
13
|
+
* Fork the project.
|
14
|
+
* Make your feature addition or bug fix.
|
15
|
+
* Add tests for it. This is important so I don't break it in a
|
16
|
+
future version unintentionally.
|
17
|
+
* Commit, do not mess with rakefile, version, or history.
|
18
|
+
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
19
|
+
* Send me a pull request. Bonus points for topic branches.
|
20
|
+
|
21
|
+
== Copyright
|
22
|
+
|
23
|
+
Copyright (c) 2010 Dan Pickett. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "exacto_subscriber"
|
8
|
+
gem.summary = %Q{Manage Exact Target List subscribers}
|
9
|
+
gem.description = %Q{Manage Exact Target List subscribers: more coming}
|
10
|
+
gem.email = "dpickett@enlightsolutions.com"
|
11
|
+
gem.homepage = "http://github.com/dpickett/exacto_subscriber"
|
12
|
+
gem.authors = ["Dan Pickett"]
|
13
|
+
gem.add_dependency "configatron", ">= 2.6.3"
|
14
|
+
gem.add_dependency "nokogiri", ">= 1.4.3.1"
|
15
|
+
gem.add_dependency "httparty", ">= 0.6.1"
|
16
|
+
gem.add_development_dependency "rspec", ">= 1.3.0"
|
17
|
+
gem.add_development_dependency "fakeweb", "1.2.8"
|
18
|
+
gem.add_development_dependency "vcr", "1.0.3"
|
19
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
20
|
+
end
|
21
|
+
Jeweler::GemcutterTasks.new
|
22
|
+
rescue LoadError
|
23
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
24
|
+
end
|
25
|
+
|
26
|
+
require 'spec/rake/spectask'
|
27
|
+
Spec::Rake::SpecTask.new(:spec) do |spec|
|
28
|
+
spec.libs << 'lib' << 'spec'
|
29
|
+
spec.spec_files = FileList['spec/**/*_spec.rb']
|
30
|
+
end
|
31
|
+
|
32
|
+
Spec::Rake::SpecTask.new(:rcov) do |spec|
|
33
|
+
spec.libs << 'lib' << 'spec'
|
34
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
35
|
+
spec.rcov = true
|
36
|
+
end
|
37
|
+
|
38
|
+
task :spec => :check_dependencies
|
39
|
+
|
40
|
+
begin
|
41
|
+
require 'reek/adapters/rake_task'
|
42
|
+
Reek::RakeTask.new do |t|
|
43
|
+
t.fail_on_error = true
|
44
|
+
t.verbose = false
|
45
|
+
t.source_files = 'lib/**/*.rb'
|
46
|
+
end
|
47
|
+
rescue LoadError
|
48
|
+
task :reek do
|
49
|
+
abort "Reek is not available. In order to run reek, you must: sudo gem install reek"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
begin
|
54
|
+
require 'roodi'
|
55
|
+
require 'roodi_task'
|
56
|
+
RoodiTask.new do |t|
|
57
|
+
t.verbose = false
|
58
|
+
end
|
59
|
+
rescue LoadError
|
60
|
+
task :roodi do
|
61
|
+
abort "Roodi is not available. In order to run roodi, you must: sudo gem install roodi"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
task :default => :spec
|
66
|
+
|
67
|
+
require 'rake/rdoctask'
|
68
|
+
Rake::RDocTask.new do |rdoc|
|
69
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
70
|
+
|
71
|
+
rdoc.rdoc_dir = 'rdoc'
|
72
|
+
rdoc.title = "exacto #{version}"
|
73
|
+
rdoc.rdoc_files.include('README*')
|
74
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
75
|
+
end
|
76
|
+
|
77
|
+
desc "obscures secure information in vcr files"
|
78
|
+
task :hide_credentials_in_cassettes do
|
79
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), 'lib'))
|
80
|
+
|
81
|
+
require "cgi"
|
82
|
+
require "exacto_subscriber"
|
83
|
+
configatron.exacto.configure_from_yaml(File.join(File.dirname(__FILE__), 'spec', 'exact_target_credentials.yml'))
|
84
|
+
|
85
|
+
Dir.glob("spec/cassettes/**/*.yml").each do |f|
|
86
|
+
contents = File.read(f)
|
87
|
+
File.open(f, "w") do |j|
|
88
|
+
j << contents.gsub(CGI.escape(Exacto.username), "<%= CGI.escape username %>").
|
89
|
+
gsub(CGI.escape(Exacto.password), "<%= CGI.escape password %>").
|
90
|
+
gsub(CGI.escape(configatron.exacto.test_list_id.to_s), "<%= CGI.escape list_id %>")
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.1
|
data/exacto.gemspec
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{exacto}
|
8
|
+
s.version = "0.1.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Dan Pickett"]
|
12
|
+
s.date = %q{2010-08-17}
|
13
|
+
s.description = %q{Manage Exact Target List subscribers: more coming}
|
14
|
+
s.email = %q{dpickett@enlightsolutions.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE",
|
17
|
+
"README.rdoc"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
".gitignore",
|
22
|
+
".rvmrc",
|
23
|
+
"LICENSE",
|
24
|
+
"README.rdoc",
|
25
|
+
"Rakefile",
|
26
|
+
"VERSION",
|
27
|
+
"lib/exacto.rb",
|
28
|
+
"lib/exacto/base.rb",
|
29
|
+
"lib/exacto/error.rb",
|
30
|
+
"lib/exacto/subscriber.rb",
|
31
|
+
"spec/cassettes/subscribers/find_by_email_and_list_id.yml",
|
32
|
+
"spec/cassettes/subscribers/subscribe.yml",
|
33
|
+
"spec/cassettes/subscribers/unsubscribe.yml",
|
34
|
+
"spec/exact_target_credentials.example.yml",
|
35
|
+
"spec/exacto/subcriber_spec.rb",
|
36
|
+
"spec/exacto_spec.rb",
|
37
|
+
"spec/spec.opts",
|
38
|
+
"spec/spec_helper.rb"
|
39
|
+
]
|
40
|
+
s.homepage = %q{http://github.com/dpickett/exacto}
|
41
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
42
|
+
s.require_paths = ["lib"]
|
43
|
+
s.rubygems_version = %q{1.3.7}
|
44
|
+
s.summary = %q{Manage Exact Target List subscribers}
|
45
|
+
s.test_files = [
|
46
|
+
"spec/exacto/subcriber_spec.rb",
|
47
|
+
"spec/exacto_spec.rb",
|
48
|
+
"spec/spec_helper.rb"
|
49
|
+
]
|
50
|
+
|
51
|
+
if s.respond_to? :specification_version then
|
52
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
53
|
+
s.specification_version = 3
|
54
|
+
|
55
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
56
|
+
s.add_runtime_dependency(%q<configatron>, [">= 2.6.3"])
|
57
|
+
s.add_runtime_dependency(%q<nokogiri>, [">= 1.4.3.1"])
|
58
|
+
s.add_runtime_dependency(%q<httparty>, [">= 0.6.1"])
|
59
|
+
s.add_development_dependency(%q<rspec>, [">= 1.3.0"])
|
60
|
+
s.add_development_dependency(%q<fakeweb>, ["= 1.2.8"])
|
61
|
+
s.add_development_dependency(%q<vcr>, ["= 1.0.3"])
|
62
|
+
else
|
63
|
+
s.add_dependency(%q<configatron>, [">= 2.6.3"])
|
64
|
+
s.add_dependency(%q<nokogiri>, [">= 1.4.3.1"])
|
65
|
+
s.add_dependency(%q<httparty>, [">= 0.6.1"])
|
66
|
+
s.add_dependency(%q<rspec>, [">= 1.3.0"])
|
67
|
+
s.add_dependency(%q<fakeweb>, ["= 1.2.8"])
|
68
|
+
s.add_dependency(%q<vcr>, ["= 1.0.3"])
|
69
|
+
end
|
70
|
+
else
|
71
|
+
s.add_dependency(%q<configatron>, [">= 2.6.3"])
|
72
|
+
s.add_dependency(%q<nokogiri>, [">= 1.4.3.1"])
|
73
|
+
s.add_dependency(%q<httparty>, [">= 0.6.1"])
|
74
|
+
s.add_dependency(%q<rspec>, [">= 1.3.0"])
|
75
|
+
s.add_dependency(%q<fakeweb>, ["= 1.2.8"])
|
76
|
+
s.add_dependency(%q<vcr>, ["= 1.0.3"])
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
@@ -0,0 +1,81 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{exacto_subscriber}
|
8
|
+
s.version = "0.1.1"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Dan Pickett"]
|
12
|
+
s.date = %q{2010-08-17}
|
13
|
+
s.description = %q{Manage Exact Target List subscribers: more coming}
|
14
|
+
s.email = %q{dpickett@enlightsolutions.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE",
|
17
|
+
"README.rdoc"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
".gitignore",
|
22
|
+
".rvmrc",
|
23
|
+
"LICENSE",
|
24
|
+
"README.rdoc",
|
25
|
+
"Rakefile",
|
26
|
+
"VERSION",
|
27
|
+
"exacto.gemspec",
|
28
|
+
"exacto_subscriber.gemspec",
|
29
|
+
"lib/exacto_subscriber.rb",
|
30
|
+
"lib/exacto_subscriber/base.rb",
|
31
|
+
"lib/exacto_subscriber/error.rb",
|
32
|
+
"lib/exacto_subscriber/subscriber.rb",
|
33
|
+
"spec/cassettes/subscribers/find_by_email_and_list_id.yml",
|
34
|
+
"spec/cassettes/subscribers/subscribe.yml",
|
35
|
+
"spec/cassettes/subscribers/unsubscribe.yml",
|
36
|
+
"spec/exact_target_credentials.example.yml",
|
37
|
+
"spec/exacto/subcriber_spec.rb",
|
38
|
+
"spec/exacto_spec.rb",
|
39
|
+
"spec/spec.opts",
|
40
|
+
"spec/spec_helper.rb"
|
41
|
+
]
|
42
|
+
s.homepage = %q{http://github.com/dpickett/exacto_subscriber}
|
43
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
44
|
+
s.require_paths = ["lib"]
|
45
|
+
s.rubygems_version = %q{1.3.7}
|
46
|
+
s.summary = %q{Manage Exact Target List subscribers}
|
47
|
+
s.test_files = [
|
48
|
+
"spec/exacto/subcriber_spec.rb",
|
49
|
+
"spec/exacto_spec.rb",
|
50
|
+
"spec/spec_helper.rb"
|
51
|
+
]
|
52
|
+
|
53
|
+
if s.respond_to? :specification_version then
|
54
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
55
|
+
s.specification_version = 3
|
56
|
+
|
57
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
58
|
+
s.add_runtime_dependency(%q<configatron>, [">= 2.6.3"])
|
59
|
+
s.add_runtime_dependency(%q<nokogiri>, [">= 1.4.3.1"])
|
60
|
+
s.add_runtime_dependency(%q<httparty>, [">= 0.6.1"])
|
61
|
+
s.add_development_dependency(%q<rspec>, [">= 1.3.0"])
|
62
|
+
s.add_development_dependency(%q<fakeweb>, ["= 1.2.8"])
|
63
|
+
s.add_development_dependency(%q<vcr>, ["= 1.0.3"])
|
64
|
+
else
|
65
|
+
s.add_dependency(%q<configatron>, [">= 2.6.3"])
|
66
|
+
s.add_dependency(%q<nokogiri>, [">= 1.4.3.1"])
|
67
|
+
s.add_dependency(%q<httparty>, [">= 0.6.1"])
|
68
|
+
s.add_dependency(%q<rspec>, [">= 1.3.0"])
|
69
|
+
s.add_dependency(%q<fakeweb>, ["= 1.2.8"])
|
70
|
+
s.add_dependency(%q<vcr>, ["= 1.0.3"])
|
71
|
+
end
|
72
|
+
else
|
73
|
+
s.add_dependency(%q<configatron>, [">= 2.6.3"])
|
74
|
+
s.add_dependency(%q<nokogiri>, [">= 1.4.3.1"])
|
75
|
+
s.add_dependency(%q<httparty>, [">= 0.6.1"])
|
76
|
+
s.add_dependency(%q<rspec>, [">= 1.3.0"])
|
77
|
+
s.add_dependency(%q<fakeweb>, ["= 1.2.8"])
|
78
|
+
s.add_dependency(%q<vcr>, ["= 1.0.3"])
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Exacto
|
2
|
+
class Base
|
3
|
+
include HTTParty
|
4
|
+
default_params :qf => 'xml'
|
5
|
+
base_uri 'https://www.exacttarget.com/api'
|
6
|
+
|
7
|
+
protected
|
8
|
+
def issue_request(&block)
|
9
|
+
self.class.issue_request(&block)
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.issue_request(&block)
|
13
|
+
if block_given?
|
14
|
+
builder = Nokogiri::XML::Builder.new do |xml|
|
15
|
+
xml.exacttarget do
|
16
|
+
xml.authorization do
|
17
|
+
xml.username Exacto.username
|
18
|
+
xml.password Exacto.password
|
19
|
+
end
|
20
|
+
xml.system do
|
21
|
+
xml.system_name system_name
|
22
|
+
yield(xml)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
resp = parse_response(post("/integrate.asp", :body => {:xml => builder.to_xml}))
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.parse_response(response)
|
32
|
+
trimmed_response = response["exacttarget"]["system"][self.system_name]
|
33
|
+
raise_errors_for(trimmed_response)
|
34
|
+
trimmed_response
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
def self.raise_errors_for(response)
|
39
|
+
Error.from_response(response)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Exacto
|
2
|
+
class Error < Exception
|
3
|
+
attr_reader :code, :messsage
|
4
|
+
def initialize(code, msg)
|
5
|
+
@code = code
|
6
|
+
@message = msg
|
7
|
+
super("Exacto Error: #{code} - #{msg}")
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.from_response(response)
|
11
|
+
if code = response["error"]
|
12
|
+
raise new(code, response["error_description"])
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
module Exacto
|
2
|
+
class Subscriber < Exacto::Base
|
3
|
+
attr_reader :email, :subscriber_id
|
4
|
+
attr_accessor :list_id, :status, :attributes
|
5
|
+
|
6
|
+
def initialize(options = {})
|
7
|
+
update_from_options(options)
|
8
|
+
end
|
9
|
+
|
10
|
+
def subscribe_to(list_id)
|
11
|
+
@list_id = list_id
|
12
|
+
if item = self.class.find_by_email_and_list_id(email, list_id)
|
13
|
+
item.list_id = list_id
|
14
|
+
item.update
|
15
|
+
else
|
16
|
+
create
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def unsubscribe_from(list_id)
|
21
|
+
@list_id = list_id
|
22
|
+
@status = "Unsubscribed"
|
23
|
+
if item = self.class.find_by_email_and_list_id(email, list_id)
|
24
|
+
item.list_id = list_id
|
25
|
+
item.status = status
|
26
|
+
item.update
|
27
|
+
else
|
28
|
+
create
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def create
|
33
|
+
issue_request do |xml|
|
34
|
+
xml.action "add"
|
35
|
+
xml.search_type "listid"
|
36
|
+
xml.search_value @list_id
|
37
|
+
xml.search_value2 nil
|
38
|
+
resource_xml(xml)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def update
|
43
|
+
result = issue_request do |xml|
|
44
|
+
xml.action "edit"
|
45
|
+
xml.search_type "listid"
|
46
|
+
xml.search_value @list_id
|
47
|
+
xml.search_value2 email
|
48
|
+
resource_xml(xml)
|
49
|
+
xml.update true
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def resource_xml(xml)
|
54
|
+
xml.values do
|
55
|
+
xml.email__address @email
|
56
|
+
xml.status @status || "active"
|
57
|
+
(self.attributes || {}).each do |field, val|
|
58
|
+
xml.send(field, val)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def destroy
|
64
|
+
issue_request do |xml|
|
65
|
+
xml.action "delete"
|
66
|
+
xml.search_type "subid"
|
67
|
+
xml.search_value subscriber_id
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def update_from_options(options)
|
72
|
+
@email = options[:email]
|
73
|
+
@status = options[:status]
|
74
|
+
@subscriber_id = options[:subscriber_id]
|
75
|
+
@attributes = options[:attributes] || {}
|
76
|
+
end
|
77
|
+
|
78
|
+
def self.find_by_email_and_list_id(email, list_id)
|
79
|
+
begin
|
80
|
+
result = issue_request do |xml|
|
81
|
+
xml.action "retrieve"
|
82
|
+
xml.search_type "listid"
|
83
|
+
xml.search_value list_id
|
84
|
+
xml.search_value2 email
|
85
|
+
xml.showChannelID nil
|
86
|
+
end
|
87
|
+
rescue Error => e
|
88
|
+
if e.code == "1"
|
89
|
+
result = nil
|
90
|
+
else
|
91
|
+
raise e
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
result.nil? ? nil : new(normalize(result))
|
96
|
+
end
|
97
|
+
|
98
|
+
def self.normalize(resulting_hash)
|
99
|
+
new_hash = {}
|
100
|
+
resulting_hash.each do |key, value|
|
101
|
+
if key =~ /subid/
|
102
|
+
new_hash[:subscriber_id] = value
|
103
|
+
elsif key =~ /Email\_\_Address/
|
104
|
+
new_hash[:email] = value
|
105
|
+
else
|
106
|
+
new_hash[key.gsub(/\_\_/, "_").gsub(/id/, "_id").downcase.to_sym] = value
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
new_hash
|
111
|
+
end
|
112
|
+
|
113
|
+
def self.system_name
|
114
|
+
"subscriber"
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require "configatron"
|
3
|
+
require "httparty"
|
4
|
+
require "nokogiri"
|
5
|
+
|
6
|
+
module Exacto
|
7
|
+
def self.user=(user)
|
8
|
+
configatron.exacto.user = user
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.username
|
12
|
+
configatron.exacto.username
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.password=(password)
|
16
|
+
configatron.exacto.password = password
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.password
|
20
|
+
configatron.exacto.password
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
require "exacto_subscriber/error"
|
25
|
+
require "exacto_subscriber/base"
|
26
|
+
|
27
|
+
require "exacto_subscriber/subscriber"
|
@@ -0,0 +1,46 @@
|
|
1
|
+
---
|
2
|
+
- !ruby/struct:VCR::HTTPInteraction
|
3
|
+
request: !ruby/struct:VCR::Request
|
4
|
+
method: :post
|
5
|
+
uri: https://www.exacttarget.com:443/api/integrate.asp?qf=xml
|
6
|
+
body: xml=%3C%3Fxml%20version%3D%221.0%22%3F%3E%0A%3Cexacttarget%3E%0A%20%20%3Cauthorization%3E%0A%20%20%20%20%3Cusername%3E<%= CGI.escape username %>%3C%2Fusername%3E%0A%20%20%20%20%3Cpassword%3E<%= CGI.escape password %>%3C%2Fpassword%3E%0A%20%20%3C%2Fauthorization%3E%0A%20%20%3Csystem%3E%0A%20%20%20%20%3Csystem_name%3Esubscriber%3C%2Fsystem_name%3E%0A%20%20%20%20%3Caction%3Eretrieve%3C%2Faction%3E%0A%20%20%20%20%3Csearch_type%3Elistid%3C%2Fsearch_type%3E%0A%20%20%20%20%3Csearch_value%3E<%= CGI.escape list_id %>%3C%2Fsearch_value%3E%0A%20%20%20%20%3Csearch_value2%3Euser3%40example.com%3C%2Fsearch_value2%3E%0A%20%20%20%20%3CshowChannelID%3E%3C%2FshowChannelID%3E%0A%20%20%3C%2Fsystem%3E%0A%3C%2Fexacttarget%3E%0A
|
7
|
+
headers:
|
8
|
+
content-type:
|
9
|
+
- application/x-www-form-urlencoded
|
10
|
+
connection:
|
11
|
+
- close
|
12
|
+
content-length:
|
13
|
+
- "677"
|
14
|
+
host:
|
15
|
+
- www.exacttarget.com
|
16
|
+
response: !ruby/struct:VCR::Response
|
17
|
+
status: !ruby/struct:VCR::ResponseStatus
|
18
|
+
code: 200
|
19
|
+
message: OK
|
20
|
+
headers:
|
21
|
+
x-powered-by:
|
22
|
+
- ASP.NET
|
23
|
+
x-aspnet-version:
|
24
|
+
- 2.0.50727
|
25
|
+
connection:
|
26
|
+
- close
|
27
|
+
content-type:
|
28
|
+
- text/xml; charset=utf-8
|
29
|
+
server:
|
30
|
+
- Microsoft-IIS/6.0
|
31
|
+
date:
|
32
|
+
- Tue, 17 Aug 2010 15:58:00 GMT
|
33
|
+
set-cookie:
|
34
|
+
- ASP.NET_SessionId=egukyha25rlc4045qizuwu45; path=/; HttpOnly
|
35
|
+
cache-control:
|
36
|
+
- private
|
37
|
+
transfer-encoding:
|
38
|
+
- chunked
|
39
|
+
body: |
|
40
|
+
<?xml version='1.0'?>
|
41
|
+
<exacttarget>
|
42
|
+
<system>
|
43
|
+
<subscriber><subid>548749517</subid><listid><%= CGI.escape list_id %></listid><list_name>Development - master</list_name><Full__Name /><Email__Address>user3@example.com</Email__Address><User__Defined /><Email__Type>HTML</Email__Type><Status>Unsubscribed</Status><First__Name>John</First__Name><Last__Name>Smith</Last__Name><Packing__Slip__Count /><Originating__Partner /></subscriber></system>
|
44
|
+
</exacttarget>
|
45
|
+
|
46
|
+
http_version: "1.1"
|
@@ -0,0 +1,136 @@
|
|
1
|
+
---
|
2
|
+
- !ruby/struct:VCR::HTTPInteraction
|
3
|
+
request: !ruby/struct:VCR::Request
|
4
|
+
method: :post
|
5
|
+
uri: https://www.exacttarget.com:443/api/integrate.asp?qf=xml
|
6
|
+
body: xml=%3C%3Fxml%20version%3D%221.0%22%3F%3E%0A%3Cexacttarget%3E%0A%20%20%3Cauthorization%3E%0A%20%20%20%20%3Cusername%3E<%= CGI.escape username %>%3C%2Fusername%3E%0A%20%20%20%20%3Cpassword%3E<%= CGI.escape password %>%3C%2Fpassword%3E%0A%20%20%3C%2Fauthorization%3E%0A%20%20%3Csystem%3E%0A%20%20%20%20%3Csystem_name%3Esubscriber%3C%2Fsystem_name%3E%0A%20%20%20%20%3Caction%3Eretrieve%3C%2Faction%3E%0A%20%20%20%20%3Csearch_type%3Elistid%3C%2Fsearch_type%3E%0A%20%20%20%20%3Csearch_value%3E<%= CGI.escape list_id %>%3C%2Fsearch_value%3E%0A%20%20%20%20%3Csearch_value2%3Euser3%40example.com%3C%2Fsearch_value2%3E%0A%20%20%20%20%3CshowChannelID%3E%3C%2FshowChannelID%3E%0A%20%20%3C%2Fsystem%3E%0A%3C%2Fexacttarget%3E%0A
|
7
|
+
headers:
|
8
|
+
content-type:
|
9
|
+
- application/x-www-form-urlencoded
|
10
|
+
connection:
|
11
|
+
- close
|
12
|
+
content-length:
|
13
|
+
- "677"
|
14
|
+
host:
|
15
|
+
- www.exacttarget.com
|
16
|
+
response: !ruby/struct:VCR::Response
|
17
|
+
status: !ruby/struct:VCR::ResponseStatus
|
18
|
+
code: 200
|
19
|
+
message: OK
|
20
|
+
headers:
|
21
|
+
x-powered-by:
|
22
|
+
- ASP.NET
|
23
|
+
x-aspnet-version:
|
24
|
+
- 2.0.50727
|
25
|
+
connection:
|
26
|
+
- close
|
27
|
+
content-type:
|
28
|
+
- text/xml; charset=utf-8
|
29
|
+
server:
|
30
|
+
- Microsoft-IIS/6.0
|
31
|
+
date:
|
32
|
+
- Tue, 17 Aug 2010 15:57:54 GMT
|
33
|
+
set-cookie:
|
34
|
+
- ASP.NET_SessionId=324tuu45y10kx455aejxgv45; path=/; HttpOnly
|
35
|
+
cache-control:
|
36
|
+
- private
|
37
|
+
transfer-encoding:
|
38
|
+
- chunked
|
39
|
+
body: |
|
40
|
+
<?xml version='1.0'?>
|
41
|
+
<exacttarget>
|
42
|
+
<system>
|
43
|
+
<subscriber><error>1</error><error_description>Subscriber not found with ListID = <%= CGI.escape list_id %> Email Address = user3@example.com</error_description></subscriber></system>
|
44
|
+
</exacttarget>
|
45
|
+
|
46
|
+
http_version: "1.1"
|
47
|
+
- !ruby/struct:VCR::HTTPInteraction
|
48
|
+
request: !ruby/struct:VCR::Request
|
49
|
+
method: :post
|
50
|
+
uri: https://www.exacttarget.com:443/api/integrate.asp?qf=xml
|
51
|
+
body: xml=%3C%3Fxml%20version%3D%221.0%22%3F%3E%0A%3Cexacttarget%3E%0A%20%20%3Cauthorization%3E%0A%20%20%20%20%3Cusername%3E<%= CGI.escape username %>%3C%2Fusername%3E%0A%20%20%20%20%3Cpassword%3E<%= CGI.escape password %>%3C%2Fpassword%3E%0A%20%20%3C%2Fauthorization%3E%0A%20%20%3Csystem%3E%0A%20%20%20%20%3Csystem_name%3Esubscriber%3C%2Fsystem_name%3E%0A%20%20%20%20%3Caction%3Eretrieve%3C%2Faction%3E%0A%20%20%20%20%3Csearch_type%3Elistid%3C%2Fsearch_type%3E%0A%20%20%20%20%3Csearch_value%3E<%= CGI.escape list_id %>%3C%2Fsearch_value%3E%0A%20%20%20%20%3Csearch_value2%3Euser3%40example.com%3C%2Fsearch_value2%3E%0A%20%20%20%20%3CshowChannelID%3E%3C%2FshowChannelID%3E%0A%20%20%3C%2Fsystem%3E%0A%3C%2Fexacttarget%3E%0A
|
52
|
+
headers:
|
53
|
+
content-type:
|
54
|
+
- application/x-www-form-urlencoded
|
55
|
+
connection:
|
56
|
+
- close
|
57
|
+
content-length:
|
58
|
+
- "677"
|
59
|
+
host:
|
60
|
+
- www.exacttarget.com
|
61
|
+
response: !ruby/struct:VCR::Response
|
62
|
+
status: !ruby/struct:VCR::ResponseStatus
|
63
|
+
code: 200
|
64
|
+
message: OK
|
65
|
+
headers:
|
66
|
+
x-powered-by:
|
67
|
+
- ASP.NET
|
68
|
+
x-aspnet-version:
|
69
|
+
- 2.0.50727
|
70
|
+
connection:
|
71
|
+
- close
|
72
|
+
content-type:
|
73
|
+
- text/xml; charset=utf-8
|
74
|
+
server:
|
75
|
+
- Microsoft-IIS/6.0
|
76
|
+
date:
|
77
|
+
- Tue, 17 Aug 2010 15:57:54 GMT
|
78
|
+
set-cookie:
|
79
|
+
- ASP.NET_SessionId=1tlfxvvo0yzaql452hz5j345; path=/; HttpOnly
|
80
|
+
cache-control:
|
81
|
+
- private
|
82
|
+
transfer-encoding:
|
83
|
+
- chunked
|
84
|
+
body: |
|
85
|
+
<?xml version='1.0'?>
|
86
|
+
<exacttarget>
|
87
|
+
<system>
|
88
|
+
<subscriber><error>1</error><error_description>Subscriber not found with ListID = <%= CGI.escape list_id %> Email Address = user3@example.com</error_description></subscriber></system>
|
89
|
+
</exacttarget>
|
90
|
+
|
91
|
+
http_version: "1.1"
|
92
|
+
- !ruby/struct:VCR::HTTPInteraction
|
93
|
+
request: !ruby/struct:VCR::Request
|
94
|
+
method: :post
|
95
|
+
uri: https://www.exacttarget.com:443/api/integrate.asp?qf=xml
|
96
|
+
body: xml=%3C%3Fxml%20version%3D%221.0%22%3F%3E%0A%3Cexacttarget%3E%0A%20%20%3Cauthorization%3E%0A%20%20%20%20%3Cusername%3E<%= CGI.escape username %>%3C%2Fusername%3E%0A%20%20%20%20%3Cpassword%3E<%= CGI.escape password %>%3C%2Fpassword%3E%0A%20%20%3C%2Fauthorization%3E%0A%20%20%3Csystem%3E%0A%20%20%20%20%3Csystem_name%3Esubscriber%3C%2Fsystem_name%3E%0A%20%20%20%20%3Caction%3Eadd%3C%2Faction%3E%0A%20%20%20%20%3Csearch_type%3Elistid%3C%2Fsearch_type%3E%0A%20%20%20%20%3Csearch_value%3E<%= CGI.escape list_id %>%3C%2Fsearch_value%3E%0A%20%20%20%20%3Csearch_value2%3E%3C%2Fsearch_value2%3E%0A%20%20%20%20%3Cvalues%3E%0A%20%20%20%20%20%20%3Cemail__address%3Euser3%40example.com%3C%2Femail__address%3E%0A%20%20%20%20%20%20%3Cstatus%3Eactive%3C%2Fstatus%3E%0A%20%20%20%20%20%20%3CLast__Name%3ESmith%3C%2FLast__Name%3E%0A%20%20%20%20%20%20%3CFirst__Name%3EJohn%3C%2FFirst__Name%3E%0A%20%20%20%20%3C%2Fvalues%3E%0A%20%20%3C%2Fsystem%3E%0A%3C%2Fexacttarget%3E%0A
|
97
|
+
headers:
|
98
|
+
content-type:
|
99
|
+
- application/x-www-form-urlencoded
|
100
|
+
connection:
|
101
|
+
- close
|
102
|
+
content-length:
|
103
|
+
- "914"
|
104
|
+
host:
|
105
|
+
- www.exacttarget.com
|
106
|
+
response: !ruby/struct:VCR::Response
|
107
|
+
status: !ruby/struct:VCR::ResponseStatus
|
108
|
+
code: 200
|
109
|
+
message: OK
|
110
|
+
headers:
|
111
|
+
x-powered-by:
|
112
|
+
- ASP.NET
|
113
|
+
x-aspnet-version:
|
114
|
+
- 2.0.50727
|
115
|
+
connection:
|
116
|
+
- close
|
117
|
+
content-type:
|
118
|
+
- text/xml; charset=utf-8
|
119
|
+
server:
|
120
|
+
- Microsoft-IIS/6.0
|
121
|
+
date:
|
122
|
+
- Tue, 17 Aug 2010 15:57:55 GMT
|
123
|
+
set-cookie:
|
124
|
+
- ASP.NET_SessionId=y1pnb3qo2vve4555dfjdlc45; path=/; HttpOnly
|
125
|
+
cache-control:
|
126
|
+
- private
|
127
|
+
transfer-encoding:
|
128
|
+
- chunked
|
129
|
+
body: |
|
130
|
+
<?xml version='1.0'?>
|
131
|
+
<exacttarget>
|
132
|
+
<system>
|
133
|
+
<subscriber><subscriber_info>Subscriber was added/updated successfully</subscriber_info><subscriber_description>548749517</subscriber_description></subscriber></system>
|
134
|
+
</exacttarget>
|
135
|
+
|
136
|
+
http_version: "1.1"
|
@@ -0,0 +1,181 @@
|
|
1
|
+
---
|
2
|
+
- !ruby/struct:VCR::HTTPInteraction
|
3
|
+
request: !ruby/struct:VCR::Request
|
4
|
+
method: :post
|
5
|
+
uri: https://www.exacttarget.com:443/api/integrate.asp?qf=xml
|
6
|
+
body: xml=%3C%3Fxml%20version%3D%221.0%22%3F%3E%0A%3Cexacttarget%3E%0A%20%20%3Cauthorization%3E%0A%20%20%20%20%3Cusername%3E<%= CGI.escape username %>%3C%2Fusername%3E%0A%20%20%20%20%3Cpassword%3E<%= CGI.escape password %>%3C%2Fpassword%3E%0A%20%20%3C%2Fauthorization%3E%0A%20%20%3Csystem%3E%0A%20%20%20%20%3Csystem_name%3Esubscriber%3C%2Fsystem_name%3E%0A%20%20%20%20%3Caction%3Eretrieve%3C%2Faction%3E%0A%20%20%20%20%3Csearch_type%3Elistid%3C%2Fsearch_type%3E%0A%20%20%20%20%3Csearch_value%3E<%= CGI.escape list_id %>%3C%2Fsearch_value%3E%0A%20%20%20%20%3Csearch_value2%3Euser3%40example.com%3C%2Fsearch_value2%3E%0A%20%20%20%20%3CshowChannelID%3E%3C%2FshowChannelID%3E%0A%20%20%3C%2Fsystem%3E%0A%3C%2Fexacttarget%3E%0A
|
7
|
+
headers:
|
8
|
+
content-type:
|
9
|
+
- application/x-www-form-urlencoded
|
10
|
+
connection:
|
11
|
+
- close
|
12
|
+
content-length:
|
13
|
+
- "677"
|
14
|
+
host:
|
15
|
+
- www.exacttarget.com
|
16
|
+
response: !ruby/struct:VCR::Response
|
17
|
+
status: !ruby/struct:VCR::ResponseStatus
|
18
|
+
code: 200
|
19
|
+
message: OK
|
20
|
+
headers:
|
21
|
+
x-powered-by:
|
22
|
+
- ASP.NET
|
23
|
+
x-aspnet-version:
|
24
|
+
- 2.0.50727
|
25
|
+
connection:
|
26
|
+
- close
|
27
|
+
content-type:
|
28
|
+
- text/xml; charset=utf-8
|
29
|
+
server:
|
30
|
+
- Microsoft-IIS/6.0
|
31
|
+
date:
|
32
|
+
- Tue, 17 Aug 2010 15:57:56 GMT
|
33
|
+
set-cookie:
|
34
|
+
- ASP.NET_SessionId=ozehg545vffjxh45we1kx5j0; path=/; HttpOnly
|
35
|
+
cache-control:
|
36
|
+
- private
|
37
|
+
transfer-encoding:
|
38
|
+
- chunked
|
39
|
+
body: |
|
40
|
+
<?xml version='1.0'?>
|
41
|
+
<exacttarget>
|
42
|
+
<system>
|
43
|
+
<subscriber><subid>548749517</subid><listid><%= CGI.escape list_id %></listid><list_name>Development - master</list_name><Full__Name /><Email__Address>user3@example.com</Email__Address><User__Defined /><Email__Type>HTML</Email__Type><Status>Active</Status><First__Name>John</First__Name><Last__Name>Smith</Last__Name><Packing__Slip__Count /><Originating__Partner /></subscriber></system>
|
44
|
+
</exacttarget>
|
45
|
+
|
46
|
+
http_version: "1.1"
|
47
|
+
- !ruby/struct:VCR::HTTPInteraction
|
48
|
+
request: !ruby/struct:VCR::Request
|
49
|
+
method: :post
|
50
|
+
uri: https://www.exacttarget.com:443/api/integrate.asp?qf=xml
|
51
|
+
body: xml=%3C%3Fxml%20version%3D%221.0%22%3F%3E%0A%3Cexacttarget%3E%0A%20%20%3Cauthorization%3E%0A%20%20%20%20%3Cusername%3E<%= CGI.escape username %>%3C%2Fusername%3E%0A%20%20%20%20%3Cpassword%3E<%= CGI.escape password %>%3C%2Fpassword%3E%0A%20%20%3C%2Fauthorization%3E%0A%20%20%3Csystem%3E%0A%20%20%20%20%3Csystem_name%3Esubscriber%3C%2Fsystem_name%3E%0A%20%20%20%20%3Caction%3Edelete%3C%2Faction%3E%0A%20%20%20%20%3Csearch_type%3Esubid%3C%2Fsearch_type%3E%0A%20%20%20%20%3Csearch_value%3E548749517%3C%2Fsearch_value%3E%0A%20%20%3C%2Fsystem%3E%0A%3C%2Fexacttarget%3E%0A
|
52
|
+
headers:
|
53
|
+
content-type:
|
54
|
+
- application/x-www-form-urlencoded
|
55
|
+
connection:
|
56
|
+
- close
|
57
|
+
content-length:
|
58
|
+
- "544"
|
59
|
+
host:
|
60
|
+
- www.exacttarget.com
|
61
|
+
response: !ruby/struct:VCR::Response
|
62
|
+
status: !ruby/struct:VCR::ResponseStatus
|
63
|
+
code: 200
|
64
|
+
message: OK
|
65
|
+
headers:
|
66
|
+
x-powered-by:
|
67
|
+
- ASP.NET
|
68
|
+
x-aspnet-version:
|
69
|
+
- 2.0.50727
|
70
|
+
connection:
|
71
|
+
- close
|
72
|
+
content-type:
|
73
|
+
- text/xml; charset=utf-8
|
74
|
+
server:
|
75
|
+
- Microsoft-IIS/6.0
|
76
|
+
date:
|
77
|
+
- Tue, 17 Aug 2010 15:57:57 GMT
|
78
|
+
set-cookie:
|
79
|
+
- ASP.NET_SessionId=o3noh1brm5lxjn2tlayuozes; path=/; HttpOnly
|
80
|
+
cache-control:
|
81
|
+
- private
|
82
|
+
transfer-encoding:
|
83
|
+
- chunked
|
84
|
+
body: |
|
85
|
+
<?xml version='1.0'?>
|
86
|
+
<exacttarget>
|
87
|
+
<system>
|
88
|
+
<subscriber><subscriber_info>Subscriber Deleted Sucessfully!</subscriber_info></subscriber></system>
|
89
|
+
</exacttarget>
|
90
|
+
|
91
|
+
http_version: "1.1"
|
92
|
+
- !ruby/struct:VCR::HTTPInteraction
|
93
|
+
request: !ruby/struct:VCR::Request
|
94
|
+
method: :post
|
95
|
+
uri: https://www.exacttarget.com:443/api/integrate.asp?qf=xml
|
96
|
+
body: xml=%3C%3Fxml%20version%3D%221.0%22%3F%3E%0A%3Cexacttarget%3E%0A%20%20%3Cauthorization%3E%0A%20%20%20%20%3Cusername%3E<%= CGI.escape username %>%3C%2Fusername%3E%0A%20%20%20%20%3Cpassword%3E<%= CGI.escape password %>%3C%2Fpassword%3E%0A%20%20%3C%2Fauthorization%3E%0A%20%20%3Csystem%3E%0A%20%20%20%20%3Csystem_name%3Esubscriber%3C%2Fsystem_name%3E%0A%20%20%20%20%3Caction%3Eretrieve%3C%2Faction%3E%0A%20%20%20%20%3Csearch_type%3Elistid%3C%2Fsearch_type%3E%0A%20%20%20%20%3Csearch_value%3E<%= CGI.escape list_id %>%3C%2Fsearch_value%3E%0A%20%20%20%20%3Csearch_value2%3Euser3%40example.com%3C%2Fsearch_value2%3E%0A%20%20%20%20%3CshowChannelID%3E%3C%2FshowChannelID%3E%0A%20%20%3C%2Fsystem%3E%0A%3C%2Fexacttarget%3E%0A
|
97
|
+
headers:
|
98
|
+
content-type:
|
99
|
+
- application/x-www-form-urlencoded
|
100
|
+
connection:
|
101
|
+
- close
|
102
|
+
content-length:
|
103
|
+
- "677"
|
104
|
+
host:
|
105
|
+
- www.exacttarget.com
|
106
|
+
response: !ruby/struct:VCR::Response
|
107
|
+
status: !ruby/struct:VCR::ResponseStatus
|
108
|
+
code: 200
|
109
|
+
message: OK
|
110
|
+
headers:
|
111
|
+
x-powered-by:
|
112
|
+
- ASP.NET
|
113
|
+
x-aspnet-version:
|
114
|
+
- 2.0.50727
|
115
|
+
connection:
|
116
|
+
- close
|
117
|
+
content-type:
|
118
|
+
- text/xml; charset=utf-8
|
119
|
+
server:
|
120
|
+
- Microsoft-IIS/6.0
|
121
|
+
date:
|
122
|
+
- Tue, 17 Aug 2010 15:57:58 GMT
|
123
|
+
set-cookie:
|
124
|
+
- ASP.NET_SessionId=doix3y55bi15fzeocix1czvl; path=/; HttpOnly
|
125
|
+
cache-control:
|
126
|
+
- private
|
127
|
+
transfer-encoding:
|
128
|
+
- chunked
|
129
|
+
body: |
|
130
|
+
<?xml version='1.0'?>
|
131
|
+
<exacttarget>
|
132
|
+
<system>
|
133
|
+
<subscriber><error>1</error><error_description>Subscriber not found with ListID = <%= CGI.escape list_id %> Email Address = user3@example.com</error_description></subscriber></system>
|
134
|
+
</exacttarget>
|
135
|
+
|
136
|
+
http_version: "1.1"
|
137
|
+
- !ruby/struct:VCR::HTTPInteraction
|
138
|
+
request: !ruby/struct:VCR::Request
|
139
|
+
method: :post
|
140
|
+
uri: https://www.exacttarget.com:443/api/integrate.asp?qf=xml
|
141
|
+
body: xml=%3C%3Fxml%20version%3D%221.0%22%3F%3E%0A%3Cexacttarget%3E%0A%20%20%3Cauthorization%3E%0A%20%20%20%20%3Cusername%3E<%= CGI.escape username %>%3C%2Fusername%3E%0A%20%20%20%20%3Cpassword%3E<%= CGI.escape password %>%3C%2Fpassword%3E%0A%20%20%3C%2Fauthorization%3E%0A%20%20%3Csystem%3E%0A%20%20%20%20%3Csystem_name%3Esubscriber%3C%2Fsystem_name%3E%0A%20%20%20%20%3Caction%3Eadd%3C%2Faction%3E%0A%20%20%20%20%3Csearch_type%3Elistid%3C%2Fsearch_type%3E%0A%20%20%20%20%3Csearch_value%3E<%= CGI.escape list_id %>%3C%2Fsearch_value%3E%0A%20%20%20%20%3Csearch_value2%3E%3C%2Fsearch_value2%3E%0A%20%20%20%20%3Cvalues%3E%0A%20%20%20%20%20%20%3Cemail__address%3Euser3%40example.com%3C%2Femail__address%3E%0A%20%20%20%20%20%20%3Cstatus%3EUnsubscribed%3C%2Fstatus%3E%0A%20%20%20%20%20%20%3CLast__Name%3ESmith%3C%2FLast__Name%3E%0A%20%20%20%20%20%20%3CFirst__Name%3EJohn%3C%2FFirst__Name%3E%0A%20%20%20%20%3C%2Fvalues%3E%0A%20%20%3C%2Fsystem%3E%0A%3C%2Fexacttarget%3E%0A
|
142
|
+
headers:
|
143
|
+
content-type:
|
144
|
+
- application/x-www-form-urlencoded
|
145
|
+
connection:
|
146
|
+
- close
|
147
|
+
content-length:
|
148
|
+
- "920"
|
149
|
+
host:
|
150
|
+
- www.exacttarget.com
|
151
|
+
response: !ruby/struct:VCR::Response
|
152
|
+
status: !ruby/struct:VCR::ResponseStatus
|
153
|
+
code: 200
|
154
|
+
message: OK
|
155
|
+
headers:
|
156
|
+
x-powered-by:
|
157
|
+
- ASP.NET
|
158
|
+
x-aspnet-version:
|
159
|
+
- 2.0.50727
|
160
|
+
connection:
|
161
|
+
- close
|
162
|
+
content-type:
|
163
|
+
- text/xml; charset=utf-8
|
164
|
+
server:
|
165
|
+
- Microsoft-IIS/6.0
|
166
|
+
date:
|
167
|
+
- Tue, 17 Aug 2010 15:57:59 GMT
|
168
|
+
set-cookie:
|
169
|
+
- ASP.NET_SessionId=cjz4qy45hoqtxm55rgfxicvv; path=/; HttpOnly
|
170
|
+
cache-control:
|
171
|
+
- private
|
172
|
+
transfer-encoding:
|
173
|
+
- chunked
|
174
|
+
body: |
|
175
|
+
<?xml version='1.0'?>
|
176
|
+
<exacttarget>
|
177
|
+
<system>
|
178
|
+
<subscriber><subscriber_info>Subscriber was added/updated successfully</subscriber_info><subscriber_description>548749517</subscriber_description></subscriber></system>
|
179
|
+
</exacttarget>
|
180
|
+
|
181
|
+
http_version: "1.1"
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Exacto::Subscriber do
|
4
|
+
let(:list_id) { configatron.exacto.test_list_id }
|
5
|
+
let(:email) { "user3@example.com" }
|
6
|
+
subject do
|
7
|
+
Exacto::Subscriber.new(
|
8
|
+
:email => email,
|
9
|
+
:attributes => {"First__Name" => "John", "Last__Name" => "Smith"})
|
10
|
+
end
|
11
|
+
|
12
|
+
describe 'subscriptions' do
|
13
|
+
before(:each) do
|
14
|
+
VCR.insert_cassette('subscribers/subscribe')
|
15
|
+
result = subject.class.find_by_email_and_list_id(email, list_id)
|
16
|
+
result.destroy if result
|
17
|
+
end
|
18
|
+
|
19
|
+
after(:each) do
|
20
|
+
VCR.eject_cassette
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should successfully subscribe someone that does not exist' do
|
24
|
+
subject.subscribe_to(list_id).should_not be_nil
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'should successfully subscribe someone that already exists' do
|
28
|
+
second_attempt = nil
|
29
|
+
subject.subscribe_to(list_id).should_not be_nil
|
30
|
+
lambda { second_attempt = subject.subscribe_to(list_id) }.should_not raise_error
|
31
|
+
second_attempt.should_not be_nil
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "unsubscribing" do
|
36
|
+
before(:each) do
|
37
|
+
VCR.insert_cassette('subscribers/unsubscribe')
|
38
|
+
result = subject.class.find_by_email_and_list_id(email, list_id)
|
39
|
+
result.destroy if result
|
40
|
+
end
|
41
|
+
|
42
|
+
after(:each) do
|
43
|
+
VCR.eject_cassette
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'should successfully unsubscribe someone that does not exist' do
|
47
|
+
subject.unsubscribe_from(list_id).should_not be_nil
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'should successfully unsubscribe someone that does exist' do
|
51
|
+
second_attempt = nil
|
52
|
+
subject.unsubscribe_from(list_id).should_not be_nil
|
53
|
+
lambda { second_attempt = subject.unsubscribe_from(list_id) }.should_not raise_error
|
54
|
+
second_attempt.should_not be_nil
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe 'finding a subscriber by email and list id' do
|
59
|
+
before(:each) do
|
60
|
+
VCR.insert_cassette('subscribers/find_by_email_and_list_id')
|
61
|
+
end
|
62
|
+
|
63
|
+
after(:each) do
|
64
|
+
VCR.eject_cassette
|
65
|
+
end
|
66
|
+
|
67
|
+
subject { Exacto::Subscriber.find_by_email_and_list_id(email, list_id) }
|
68
|
+
|
69
|
+
it { should_not be_nil }
|
70
|
+
its(:email) { should_not be_nil }
|
71
|
+
its(:subscriber_id) {should_not be_nil}
|
72
|
+
end
|
73
|
+
end
|
data/spec/exacto_spec.rb
ADDED
data/spec/spec.opts
ADDED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
|
+
require 'exacto_subscriber'
|
4
|
+
require 'spec'
|
5
|
+
require 'spec/autorun'
|
6
|
+
|
7
|
+
require 'vcr'
|
8
|
+
require 'cgi'
|
9
|
+
|
10
|
+
configatron.exacto.configure_from_yaml(File.join(File.dirname(__FILE__), 'exact_target_credentials.yml'))
|
11
|
+
|
12
|
+
VCR.config do |c|
|
13
|
+
c.cassette_library_dir = File.join(File.dirname(__FILE__), 'cassettes')
|
14
|
+
c.http_stubbing_library = :fakeweb
|
15
|
+
c.default_cassette_options = {
|
16
|
+
:record => :new_episodes
|
17
|
+
}
|
18
|
+
end
|
19
|
+
|
20
|
+
# we must hack VCR to always use erb for secure parameters
|
21
|
+
module VCR
|
22
|
+
alias_method :orig_insert_cassette, :insert_cassette
|
23
|
+
def insert_cassette(*args)
|
24
|
+
args << {} if args.size == 1
|
25
|
+
args.last.merge!(:erb => {
|
26
|
+
:username => configatron.exacto.username,
|
27
|
+
:password => configatron.exacto.password,
|
28
|
+
:list_id => configatron.exacto.test_list_id.to_s
|
29
|
+
})
|
30
|
+
|
31
|
+
orig_insert_cassette(*args)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
Spec::Runner.configure do |config|
|
36
|
+
end
|
metadata
ADDED
@@ -0,0 +1,186 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: exacto_subscriber
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 25
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 1
|
10
|
+
version: 0.1.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Dan Pickett
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-08-17 00:00:00 -04:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: configatron
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 17
|
30
|
+
segments:
|
31
|
+
- 2
|
32
|
+
- 6
|
33
|
+
- 3
|
34
|
+
version: 2.6.3
|
35
|
+
type: :runtime
|
36
|
+
version_requirements: *id001
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: nokogiri
|
39
|
+
prerelease: false
|
40
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ">="
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
hash: 113
|
46
|
+
segments:
|
47
|
+
- 1
|
48
|
+
- 4
|
49
|
+
- 3
|
50
|
+
- 1
|
51
|
+
version: 1.4.3.1
|
52
|
+
type: :runtime
|
53
|
+
version_requirements: *id002
|
54
|
+
- !ruby/object:Gem::Dependency
|
55
|
+
name: httparty
|
56
|
+
prerelease: false
|
57
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
58
|
+
none: false
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
hash: 5
|
63
|
+
segments:
|
64
|
+
- 0
|
65
|
+
- 6
|
66
|
+
- 1
|
67
|
+
version: 0.6.1
|
68
|
+
type: :runtime
|
69
|
+
version_requirements: *id003
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: rspec
|
72
|
+
prerelease: false
|
73
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
hash: 27
|
79
|
+
segments:
|
80
|
+
- 1
|
81
|
+
- 3
|
82
|
+
- 0
|
83
|
+
version: 1.3.0
|
84
|
+
type: :development
|
85
|
+
version_requirements: *id004
|
86
|
+
- !ruby/object:Gem::Dependency
|
87
|
+
name: fakeweb
|
88
|
+
prerelease: false
|
89
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
90
|
+
none: false
|
91
|
+
requirements:
|
92
|
+
- - "="
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
hash: 15
|
95
|
+
segments:
|
96
|
+
- 1
|
97
|
+
- 2
|
98
|
+
- 8
|
99
|
+
version: 1.2.8
|
100
|
+
type: :development
|
101
|
+
version_requirements: *id005
|
102
|
+
- !ruby/object:Gem::Dependency
|
103
|
+
name: vcr
|
104
|
+
prerelease: false
|
105
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
106
|
+
none: false
|
107
|
+
requirements:
|
108
|
+
- - "="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
hash: 17
|
111
|
+
segments:
|
112
|
+
- 1
|
113
|
+
- 0
|
114
|
+
- 3
|
115
|
+
version: 1.0.3
|
116
|
+
type: :development
|
117
|
+
version_requirements: *id006
|
118
|
+
description: "Manage Exact Target List subscribers: more coming"
|
119
|
+
email: dpickett@enlightsolutions.com
|
120
|
+
executables: []
|
121
|
+
|
122
|
+
extensions: []
|
123
|
+
|
124
|
+
extra_rdoc_files:
|
125
|
+
- LICENSE
|
126
|
+
- README.rdoc
|
127
|
+
files:
|
128
|
+
- .document
|
129
|
+
- .gitignore
|
130
|
+
- .rvmrc
|
131
|
+
- LICENSE
|
132
|
+
- README.rdoc
|
133
|
+
- Rakefile
|
134
|
+
- VERSION
|
135
|
+
- exacto.gemspec
|
136
|
+
- exacto_subscriber.gemspec
|
137
|
+
- lib/exacto_subscriber.rb
|
138
|
+
- lib/exacto_subscriber/base.rb
|
139
|
+
- lib/exacto_subscriber/error.rb
|
140
|
+
- lib/exacto_subscriber/subscriber.rb
|
141
|
+
- spec/cassettes/subscribers/find_by_email_and_list_id.yml
|
142
|
+
- spec/cassettes/subscribers/subscribe.yml
|
143
|
+
- spec/cassettes/subscribers/unsubscribe.yml
|
144
|
+
- spec/exact_target_credentials.example.yml
|
145
|
+
- spec/exacto/subcriber_spec.rb
|
146
|
+
- spec/exacto_spec.rb
|
147
|
+
- spec/spec.opts
|
148
|
+
- spec/spec_helper.rb
|
149
|
+
has_rdoc: true
|
150
|
+
homepage: http://github.com/dpickett/exacto_subscriber
|
151
|
+
licenses: []
|
152
|
+
|
153
|
+
post_install_message:
|
154
|
+
rdoc_options:
|
155
|
+
- --charset=UTF-8
|
156
|
+
require_paths:
|
157
|
+
- lib
|
158
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
159
|
+
none: false
|
160
|
+
requirements:
|
161
|
+
- - ">="
|
162
|
+
- !ruby/object:Gem::Version
|
163
|
+
hash: 3
|
164
|
+
segments:
|
165
|
+
- 0
|
166
|
+
version: "0"
|
167
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
168
|
+
none: false
|
169
|
+
requirements:
|
170
|
+
- - ">="
|
171
|
+
- !ruby/object:Gem::Version
|
172
|
+
hash: 3
|
173
|
+
segments:
|
174
|
+
- 0
|
175
|
+
version: "0"
|
176
|
+
requirements: []
|
177
|
+
|
178
|
+
rubyforge_project:
|
179
|
+
rubygems_version: 1.3.7
|
180
|
+
signing_key:
|
181
|
+
specification_version: 3
|
182
|
+
summary: Manage Exact Target List subscribers
|
183
|
+
test_files:
|
184
|
+
- spec/exacto/subcriber_spec.rb
|
185
|
+
- spec/exacto_spec.rb
|
186
|
+
- spec/spec_helper.rb
|