rbet 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. data/README.rdoc +39 -0
  2. data/Rakefile +56 -0
  3. data/lib/rbet.rb +31 -0
  4. data/lib/rbet/auth.rxml +8 -0
  5. data/lib/rbet/client.rb +87 -0
  6. data/lib/rbet/error.rb +50 -0
  7. data/lib/rbet/list.rb +149 -0
  8. data/lib/rbet/list_add.rxml +8 -0
  9. data/lib/rbet/list_list_all.rxml +6 -0
  10. data/lib/rbet/list_retrieve.rxml +6 -0
  11. data/lib/rbet/list_retrieve_subscribers.rxml +6 -0
  12. data/lib/rbet/list_send_email.rxml +12 -0
  13. data/lib/rbet/ping.rxml +4 -0
  14. data/lib/rbet/renderable.rb +41 -0
  15. data/lib/rbet/subscriber.rb +137 -0
  16. data/lib/rbet/subscriber_add.rxml +15 -0
  17. data/lib/rbet/subscriber_delete.rxml +7 -0
  18. data/lib/rbet/subscriber_retrieve.rxml +8 -0
  19. data/lib/rbet/subscriber_retrieve_by_id.rxml +8 -0
  20. data/lib/rbet/subscriber_update.rxml +17 -0
  21. data/lib/rbet/tracker.rb +57 -0
  22. data/lib/rbet/tracker_retrieve_summary.rxml +8 -0
  23. data/lib/rbet/triggered_send.rb +60 -0
  24. data/lib/rbet/triggered_send.rxml +21 -0
  25. data/lib/rbet/version.rb +13 -0
  26. data/test/client_test.rb +18 -0
  27. data/test/help.rb +121 -0
  28. data/test/list_test.rb +18 -0
  29. data/test/subscriber_test.rb +18 -0
  30. data/test/templates/diagnostics_ping_success.rxml +5 -0
  31. data/test/templates/list_add_failure.rxml +6 -0
  32. data/test/templates/list_add_success.rxml +9 -0
  33. data/test/templates/list_retrieve_all_success.rxml +12 -0
  34. data/test/templates/list_retrieve_bylistid_success.rxml +15 -0
  35. data/test/templates/subscriber_add_success.rxml +6 -0
  36. data/test/templates/subscriber_retrieve_failed.rxml +9 -0
  37. data/test/templates/subscriber_retrieve_success.rxml +15 -0
  38. metadata +92 -0
@@ -0,0 +1,39 @@
1
+ == Ruby Library for ExactTarget
2
+
3
+ This is an attempt to make integrating easier with ExactTarget. ExactTarget is
4
+ an email newsletter system designed to make it easy to setup timely newsletters.
5
+
6
+ Exact Target: http://www.exacttarget.com/
7
+
8
+ Exact Target API:
9
+ http://developers.exacttarget.com/Web/help/Overview/Introduction_to_ExactTarget_API_Help.htm
10
+
11
+ == Adding rbet to a Rails Project
12
+
13
+ If you are using Git to manage your rails project and would like to add rbet as a submodule:
14
+
15
+ git submodule add git://github.com/sbraford/rbet.git vendor/rbet
16
+
17
+ Then in the bottom of your environment.rb, or in an initializer, add:
18
+
19
+ require File.join(RAILS_ROOT, 'vendor', 'rbet', 'lib', 'et.rb')
20
+
21
+ == Development Notes
22
+
23
+ Original development work was performed by Todd A. Fisher.
24
+
25
+ Forking development to GitHub + minor development additions/changes by Shanti A. Braford.
26
+
27
+ == Contributing
28
+
29
+ If you'd like to contribute, fork a copy of the repo on GitHub.
30
+
31
+ When you have patch(es) ready, contact me at:shantibraford@gmail.com
32
+
33
+ == Notes
34
+
35
+ 2000 character limit for each attribute
36
+
37
+ == Win32 Notes
38
+
39
+ This has not been tested on Windows. May the force be with you, young win32 jedi =)
@@ -0,0 +1,56 @@
1
+ require 'rubygems'
2
+ require 'rake/gempackagetask'
3
+ require 'rake/testtask'
4
+ require 'rake/rdoctask'
5
+ require 'lib/rbet/version'
6
+
7
+ spec = Gem::Specification.new do |s|
8
+ s.name = 'rbet'
9
+ s.version = RBET::Version.to_s
10
+ s.has_rdoc = true
11
+ s.extra_rdoc_files = %w(README.rdoc)
12
+ s.rdoc_options = %w(--main README.rdoc)
13
+ s.summary = "A ruby wrapper for the Exact Target API"
14
+ s.author = 'See Contributing Section'
15
+ s.email = 'kevin@conceptsahead.com'
16
+ s.homepage = 'http://github.com/n3bulous/rbet'
17
+ s.files = %w(README.rdoc Rakefile) + Dir.glob("{lib,test}/**/*")
18
+ # s.executables = ['rbet']
19
+
20
+ # s.add_dependency('gem_name', '~> 0.0.1')
21
+ end
22
+
23
+ Rake::GemPackageTask.new(spec) do |pkg|
24
+ pkg.gem_spec = spec
25
+ end
26
+
27
+ Rake::TestTask.new do |t|
28
+ t.libs << 'test'
29
+ t.test_files = FileList["test/*_test.rb"]
30
+ t.verbose = true
31
+ end
32
+
33
+ begin
34
+ require 'rcov/rcovtask'
35
+
36
+ Rcov::RcovTask.new(:coverage) do |t|
37
+ t.libs = ['test']
38
+ t.test_files = FileList["test/*_test.rb"]
39
+ t.verbose = true
40
+ t.rcov_opts = ['--text-report', "-x #{Gem.path}", '-x /Library/Ruby', '-x /usr/lib/ruby']
41
+ end
42
+
43
+ task :default => :coverage
44
+
45
+ rescue LoadError
46
+ warn "\n**** Install rcov (sudo gem install relevance-rcov) to get coverage stats ****\n"
47
+ task :default => :test
48
+ end
49
+
50
+
51
+ desc 'Generate the gemspec to serve this Gem from Github'
52
+ task :github do
53
+ file = File.dirname(__FILE__) + "/#{spec.name}.gemspec"
54
+ File.open(file, 'w') {|f| f << spec.to_ruby }
55
+ puts "Created gemspec: #{file}"
56
+ end
@@ -0,0 +1,31 @@
1
+ #
2
+ # Copyright (c) 2007 Todd A. Fisher
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included
13
+ # in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18
+ # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19
+ # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21
+ # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #
23
+
24
+ require 'rubygems'
25
+ gem 'activesupport'
26
+ require 'active_support'
27
+
28
+ $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + "/rbet"))
29
+ %w(renderable error client subscriber list tracker triggered_send).each do |lib|
30
+ require lib
31
+ end
@@ -0,0 +1,8 @@
1
+ <?xml version="1.0" ?>
2
+ <exacttarget>
3
+ <authorization>
4
+ <username><%= @username %></username>
5
+ <password><%= @password %></password>
6
+ </authorization>
7
+ <%= @system %>
8
+ </exacttarget>
@@ -0,0 +1,87 @@
1
+ #
2
+ # Copyright (c) 2007 Todd A. Fisher
3
+ #
4
+ # Portions Copyright (c) 2008 Shanti A. Braford
5
+ #
6
+ # Permission is hereby granted, free of charge, to any person obtaining
7
+ # a copy of this software and associated documentation files (the
8
+ # "Software"), to deal in the Software without restriction, including
9
+ # without limitation the rights to use, copy, modify, merge, publish,
10
+ # distribute, sublicense, and/or sell copies of the Software, and to
11
+ # permit persons to whom the Software is furnished to do so, subject to
12
+ # the following conditions:
13
+ #
14
+ # The above copyright notice and this permission notice shall be included
15
+ # in all copies or substantial portions of the Software.
16
+ #
17
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20
+ # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21
+ # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23
+ # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
+ #
25
+ require 'net/https'
26
+ require 'uri'
27
+ require 'erb'
28
+
29
+ module RBET
30
+ class Client
31
+ attr_reader :username, :password, :headers
32
+ include RBET::Renderable
33
+
34
+ # Initializes a new ET::Client object
35
+ #
36
+ # Usaage:
37
+ #
38
+ # client = ET::Client.new('tester','tester11', {:service_url => 'http://127.0.0.1:99999/test/', :use_ssl => false})
39
+ # client.status
40
+ # => "Running"
41
+ # client.live?
42
+ # => true
43
+ #
44
+ def initialize(username,password,options={})
45
+ @username = username
46
+ @password = password
47
+ service_url = options[:service_url] ? options[:service_url] : 'https://www.exacttarget.com/api/integrate.asp?qf=xml'
48
+ @uri = URI.parse(service_url)
49
+ @url = Net::HTTP.new(@uri.host, @uri.port)
50
+ @url.use_ssl = options.key?(:use_ssl) ? options[:use_ssl] : true
51
+ @url.set_debug_output options.key?(:debug_output) ? options[:debug_output] : nil
52
+ @headers = {
53
+ 'Content-Type' => 'application/x-www-form-urlencoded'
54
+ }
55
+ end
56
+
57
+ # Boolean value of whether the service is running or not currently
58
+ def live?
59
+ @current_status ||= status
60
+ @current_status == 'Running'
61
+ end
62
+
63
+ # Returns the string value from the ExactTarget API ping method. ("Running" when the system is operational)
64
+ def status
65
+ response = send do|io|
66
+ io << render_template('ping')
67
+ end
68
+ Error.check_response_error(response)
69
+ doc = Hpricot.XML( response.read_body )
70
+ @current_status = doc.at("Ping").inner_html
71
+ end
72
+
73
+ # usage:
74
+ # send do|io|
75
+ # io << 'more xml'
76
+ # end
77
+ def send
78
+ @system = ""
79
+ yield @system
80
+
81
+ result = 'qf=xml&xml=' + render_template( 'auth' )
82
+
83
+ @url.post( @uri.path, result, @headers.merge('Content-length' => result.length.to_s) )
84
+ end
85
+
86
+ end
87
+ end
@@ -0,0 +1,50 @@
1
+ #
2
+ # Copyright (c) 2007 Todd A. Fisher
3
+ #
4
+ # Portions Copyright (c) 2008 Shanti A. Braford
5
+ #
6
+ # Permission is hereby granted, free of charge, to any person obtaining
7
+ # a copy of this software and associated documentation files (the
8
+ # "Software"), to deal in the Software without restriction, including
9
+ # without limitation the rights to use, copy, modify, merge, publish,
10
+ # distribute, sublicense, and/or sell copies of the Software, and to
11
+ # permit persons to whom the Software is furnished to do so, subject to
12
+ # the following conditions:
13
+ #
14
+ # The above copyright notice and this permission notice shall be included
15
+ # in all copies or substantial portions of the Software.
16
+ #
17
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20
+ # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21
+ # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23
+ # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
+ #
25
+ module RBET
26
+ class Error < RuntimeError
27
+ attr_reader :code, :message
28
+ def initialize(error_code,error_msg)
29
+ @code = error_code
30
+ @message = error_msg
31
+ end
32
+
33
+ def to_s
34
+ "Code: #{@code}. Message: #{@message}"
35
+ end
36
+
37
+ # raise a new error object from an HTTP response if it contains an error
38
+ def self.check_response_error(response)
39
+ if response.class != Net::HTTPOK
40
+ raise Error.new(-1,'Network error')
41
+ end
42
+ doc = Hpricot.XML(response.body)
43
+ error_code = doc.at("error")
44
+ error_msg = doc.at("error_description")
45
+ if( error_code and error_msg )
46
+ raise Error.new(error_code.inner_html.to_i,error_msg.inner_html)
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,149 @@
1
+ #
2
+ # Copyright (c) 2007 Todd A. Fisher
3
+ #
4
+ # Portions Copyright (c) 2008 Shanti A. Braford
5
+ #
6
+ # Permission is hereby granted, free of charge, to any person obtaining
7
+ # a copy of this software and associated documentation files (the
8
+ # "Software"), to deal in the Software without restriction, including
9
+ # without limitation the rights to use, copy, modify, merge, publish,
10
+ # distribute, sublicense, and/or sell copies of the Software, and to
11
+ # permit persons to whom the Software is furnished to do so, subject to
12
+ # the following conditions:
13
+ #
14
+ # The above copyright notice and this permission notice shall be included
15
+ # in all copies or substantial portions of the Software.
16
+ #
17
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20
+ # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21
+ # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23
+ # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
+ #
25
+ module RBET
26
+ #
27
+ # Subscriber list
28
+ # usage:
29
+ #
30
+ # # create a new subscriber list
31
+ # super_list = List.add 'Super list', :type => :public
32
+ # => ET::List
33
+ #
34
+ # # retrieve the list by name
35
+ # basic_list = List.retrieve_by_name('My Super List')
36
+ # => ET::List
37
+ #
38
+ # # retrieve by id
39
+ # basic_list = List.retrieve_by_id(12322)
40
+ # => ET::List
41
+ #
42
+ # # send an email to a list
43
+ # list_id = 147000
44
+ # email_template_id = 9999123
45
+ # list = ET::List.new('username', 'password')
46
+ # list.send_email(list_id, email_template_id, {:first_name => 'John', :last_name => 'Wayne'})
47
+ #
48
+ class List < Client
49
+ attr_reader :attributes
50
+
51
+ def initialize(username,password,options={})
52
+ super
53
+ @attributes = {}
54
+ end
55
+
56
+ # get all the lists
57
+ def all
58
+ response = send do|io|
59
+ io << render_template('list_list_all')
60
+ end
61
+ Error.check_response_error(response)
62
+ doc = Hpricot.XML( response.read_body )
63
+ listids = []
64
+ (doc/"listid").each do|listid|
65
+ listids << listid.inner_html.to_i
66
+ end
67
+ listids
68
+ end
69
+
70
+ # returns a new list object by id
71
+ def retrieve_by_id( id )
72
+ @search_type = "listid"
73
+ @search_value = id
74
+ response = send do|io|
75
+ io << render_template('list_retrieve')
76
+ end
77
+ Error.check_response_error(response)
78
+ load_list( response.read_body )
79
+ end
80
+
81
+ # returns a new list object by list name
82
+ def retrieve_by_name( name )
83
+ @search_type = "listname"
84
+ @search_value = name
85
+ response = send do|io|
86
+ io << render_template('list_retrieve')
87
+ end
88
+ Error.check_response_error(response)
89
+ load_list( response.read_body )
90
+ end
91
+
92
+ # defaults type to private if not private or public
93
+ # returns the new list id
94
+ def add(name, type='private')
95
+ @list_name = name
96
+ @list_type = type
97
+ @list_type = 'private' if type != 'public' or type != 'private'
98
+ response = send do|io|
99
+ io << render_template('list_add')
100
+ end
101
+ Error.check_response_error(response)
102
+ doc = Hpricot.XML( response.read_body )
103
+ doc.at("list_description").inner_html.to_i
104
+ end
105
+
106
+ def subscriber_emails(list_id)
107
+ @list_id = list_id
108
+ response = send do|io|
109
+ io << render_template('list_retrieve_subscribers')
110
+ end
111
+ Error.check_response_error(response)
112
+ body = response.read_body
113
+ doc = Hpricot.XML( body )
114
+ emails = []
115
+ (doc/"Email__Address").each do |row|
116
+ emails << row.inner_html
117
+ end
118
+ emails
119
+ end
120
+
121
+ # Sends an email to the list specified
122
+ def send_email(list_id, email_id, attrs = {})
123
+ defaults = {:from_name => '', :from_email => '', :additional => '',
124
+ :multipart_mime => true, :track_links => true, :send_date => 'immediate', :send_time => ''}
125
+ @list_id, @email_id = list_id, email_id
126
+ @extra_attrs = defaults.merge(attrs)
127
+ response = send do|io|
128
+ io << render_template('list_send_email')
129
+ end
130
+ Error.check_response_error(response)
131
+ #puts "Response Body: #{response.read_body} \n"
132
+ doc = Hpricot.XML( response.read_body )
133
+ doc.at("job_description").inner_html.to_i rescue nil
134
+ end
135
+
136
+ private
137
+
138
+ def load_list( body )
139
+ doc = Hpricot.XML( body )
140
+ doc.at("list").each_child do|child|
141
+ if child.respond_to?(:name) and child.respond_to?(:inner_html)
142
+ @attributes[child.name] = child.inner_html
143
+ end
144
+ end
145
+ self
146
+ end
147
+
148
+ end
149
+ end
@@ -0,0 +1,8 @@
1
+ <system>
2
+ <system_name>list</system_name>
3
+ <action>add</action>
4
+ <search_type></search_type>
5
+ <search_value></search_value>
6
+ <list_type><%= @list_type %></list_type>
7
+ <list_name><%= @list_name %></list_name>
8
+ </system>
@@ -0,0 +1,6 @@
1
+ <system>
2
+ <system_name>list</system_name>
3
+ <action>retrieve</action>
4
+ <search_type>listname</search_type>
5
+ <search_value></search_value>
6
+ </system>
@@ -0,0 +1,6 @@
1
+ <system>
2
+ <system_name>list</system_name>
3
+ <action>retrieve</action>
4
+ <search_type><%= @search_type %></search_type>
5
+ <search_value><%= @search_value %></search_value>
6
+ </system>
@@ -0,0 +1,6 @@
1
+ <system>
2
+ <system_name>list</system_name>
3
+ <action>retrieve_sub</action>
4
+ <search_type>listid</search_type>
5
+ <search_value><%= @list_id %></search_value>
6
+ </system>
@@ -0,0 +1,12 @@
1
+ <system>
2
+ <system_name>job</system_name>
3
+ <action>send</action>
4
+ <search_type>emailid</search_type>
5
+ <search_value><%= @email_id %></search_value>
6
+ <% @extra_attrs.each do|name, value| %>
7
+ <<%= name.to_s %>><%= value.to_s %></<%= name %>>
8
+ <% end %>
9
+ <lists>
10
+ <list><%= @list_id %></list>
11
+ </lists>
12
+ </system>
@@ -0,0 +1,4 @@
1
+ <system>
2
+ <system_name>diagnostics</system_name>
3
+ <action>Ping</action>
4
+ </system>
@@ -0,0 +1,41 @@
1
+ #
2
+ # Copyright (c) 2007 Todd A. Fisher
3
+ #
4
+ # Portions Copyright (c) 2008 Shanti A. Braford
5
+ #
6
+ # Permission is hereby granted, free of charge, to any person obtaining
7
+ # a copy of this software and associated documentation files (the
8
+ # "Software"), to deal in the Software without restriction, including
9
+ # without limitation the rights to use, copy, modify, merge, publish,
10
+ # distribute, sublicense, and/or sell copies of the Software, and to
11
+ # permit persons to whom the Software is furnished to do so, subject to
12
+ # the following conditions:
13
+ #
14
+ # The above copyright notice and this permission notice shall be included
15
+ # in all copies or substantial portions of the Software.
16
+ #
17
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20
+ # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21
+ # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23
+ # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
+ #
25
+ module RBET
26
+ module Renderable
27
+ def set_template_path(path)
28
+ @template_path = path
29
+ end
30
+
31
+ def template_path(name)
32
+ File.join( (@template_path || File.dirname(__FILE__)), "#{name}.rxml")
33
+ end
34
+
35
+ def render_template( name )
36
+ erb = ERB.new( File.open( template_path(name) ,"r").read, 0, "<>")
37
+ erb.result( binding )
38
+ end
39
+
40
+ end
41
+ end
@@ -0,0 +1,137 @@
1
+ #
2
+ # Copyright (c) 2007 Todd A. Fisher
3
+ #
4
+ # Portions Copyright (c) 2008 Shanti A. Braford
5
+ #
6
+ # Permission is hereby granted, free of charge, to any person obtaining
7
+ # a copy of this software and associated documentation files (the
8
+ # "Software"), to deal in the Software without restriction, including
9
+ # without limitation the rights to use, copy, modify, merge, publish,
10
+ # distribute, sublicense, and/or sell copies of the Software, and to
11
+ # permit persons to whom the Software is furnished to do so, subject to
12
+ # the following conditions:
13
+ #
14
+ # The above copyright notice and this permission notice shall be included
15
+ # in all copies or substantial portions of the Software.
16
+ #
17
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20
+ # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21
+ # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23
+ # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
+
25
+ require 'rubygems'
26
+ require 'hpricot'
27
+
28
+ module RBET
29
+
30
+ #
31
+ # usage:
32
+ #
33
+ # # get an existing subscriber
34
+ # subscriber = Subscriber.load!('user@example.com')
35
+ # => ET::Subscriber
36
+ #
37
+ # # subscribe a new user to an existing list
38
+ # subscriber = Subscriber.add('user@example.com',list)
39
+ # => ET::Subscriber
40
+ #
41
+ class Subscriber < Client
42
+ attr_accessor :attrs
43
+ attr_reader :email, :status
44
+
45
+ def initialize(username,password,options={})
46
+ super
47
+ @attrs = {}
48
+ end
49
+
50
+ def load!(email)
51
+ @email = email
52
+ response = send do|io|
53
+ io << render_template('subscriber_retrieve')
54
+ end
55
+ Error.check_response_error(response)
56
+ load_response(response.read_body)
57
+ end
58
+
59
+ def load_response(body)
60
+ doc = Hpricot.XML(body)
61
+ subscriber = doc.at(:subscriber)
62
+ # load elements into the attrs hash
63
+ @attrs = {}
64
+ subscriber.each_child do|attr_element|
65
+ if attr_element.elem?
66
+ name = attr_element.name.gsub(/__/,' ')
67
+ value = attr_element.inner_html
68
+ @attrs[name] = value
69
+ if name == 'Email Address'
70
+ @email = value
71
+ elsif name == 'Status'
72
+ @status = value
73
+ end
74
+ end
75
+ end
76
+ end
77
+ private :load_response
78
+
79
+ # desc:
80
+ # add this user as a new subscriber to the list, with a set of attributes
81
+ # params:
82
+ # listid: id of the e-mail list to subscribe this user to
83
+ # email: E-mail address of subscriber
84
+ def add( email, listid, attributes ={} )
85
+ @email = email
86
+ @subscriber_listid = listid
87
+ @attributes = attributes
88
+ response = send do|io|
89
+ io << render_template('subscriber_add')
90
+ end
91
+ Error.check_response_error(response)
92
+ doc = Hpricot.XML(response.read_body)
93
+ doc.at("subscriber_description").inner_html.to_i
94
+ end
95
+
96
+ # desc:
97
+ # update this a subscriber
98
+ # params:
99
+ # listid: id of the e-mail list to subscribe this user to
100
+ # email: E-mail address of subscriber
101
+ # subscriberid: id for the subscriber to update
102
+ def update(subscriberid, email, listid, attributes ={} )
103
+ @email = email
104
+ @listid = listid
105
+ @subscriberid = subscriberid
106
+ @attributes = attributes
107
+ response = send do|io|
108
+ io << render_template('subscriber_update')
109
+ end
110
+ Error.check_response_error(response)
111
+ doc = Hpricot.XML(response.read_body)
112
+ doc.at("subscriber_description").inner_html.to_i
113
+ end
114
+
115
+ # desc:
116
+ # delete this user as a new subscriber to the list, or completely from ET
117
+ # params:
118
+ # listid: id of the e-mail list to unsubscribe this user from
119
+ # email: E-mail address of subscriber
120
+ # subscriberid: id for the subscriber to delete COMPLETELY
121
+ def delete(subscriberid, email, listid, attributes ={} )
122
+ @email = email
123
+ @subscriber_listid = listid
124
+ @subscriberid = subscriberid
125
+
126
+ puts render_template('subscriber_delete')
127
+ response = send do|io|
128
+ io << render_template('subscriber_delete')
129
+ end
130
+ Error.check_response_error(response)
131
+ doc = Hpricot.XML(response.read_body)
132
+ doc.at("subscriber_info").inner_html
133
+ end
134
+
135
+
136
+ end
137
+ end
@@ -0,0 +1,15 @@
1
+ <system>
2
+ <system_name>subscriber</system_name>
3
+ <action>add</action>
4
+ <search_type>listid</search_type>
5
+ <search_value><%= @subscriber_listid %></search_value>
6
+ <search_value2></search_value2>
7
+ <values>
8
+ <Email__Address><%= @email %></Email__Address>
9
+ <status>active</status>
10
+ <% @attributes.each do|name,value| %>
11
+ <<%= name %>><%= (value.is_a?(Array)) ? value.join(',') : value %></<%= name %>>
12
+ <% end %>
13
+ </values>
14
+ <update>true</update>
15
+ </system>
@@ -0,0 +1,7 @@
1
+ <system>
2
+ <system_name>subscriber</system_name>
3
+ <action>delete</action>
4
+ <search_type><%= @subscriberid.nil? ? "listid" : "subid" %></search_type>
5
+ <search_value><%= @subscriberid.nil? ? @subscriber_listid : @subscriberid %></search_value>
6
+ <search_value2><%= @email if @subscriberid.nil? %></search_value2>
7
+ </system>
@@ -0,0 +1,8 @@
1
+ <system>
2
+ <system_name>subscriber</system_name>
3
+ <action>retrieve</action>
4
+ <search_type>listid</search_type>
5
+ <search_value><%= @list_id %></search_value>
6
+ <search_value2><%= @email %></search_value2>
7
+ <showChannelID></showChannelID>
8
+ </system>
@@ -0,0 +1,8 @@
1
+ <system>
2
+ <system_name>subscriber</system_name>
3
+ <action>retrieve</action>
4
+ <search_type>subid</search_type>
5
+ <search_value><%= @subid %></search_value>
6
+ <search_value2></search_value2>
7
+ <showChannelID></showChannelID>
8
+ </system>
@@ -0,0 +1,17 @@
1
+ <system>
2
+ <system_name>subscriber</system_name>
3
+ <action>edit</action>
4
+ <search_type><%= @subscriberid.nil? ? "listid" : "subid" %></search_type>
5
+ <search_value><%= @subscriberid.nil? ? @listid : @subscriberid %></search_value>
6
+ <search_value2><%= @email unless @subscriberid.nil? %></search_value2>
7
+ <values>
8
+ <Email__Address><%= @email %></Email__Address>
9
+ <% unless @listid.nil? %>
10
+ <status>active</status>
11
+ <% end %>
12
+ <% @attributes.each do|name,value| %>
13
+ <<%= name %>><%= (value.is_a?(Array)) ? value.join(',') : value %></<%= name %>>
14
+ <% end %>
15
+ </values>
16
+ <update>true</update>
17
+ </system>
@@ -0,0 +1,57 @@
1
+ #
2
+ # Copyright (c) 2008 Shanti A. Braford
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included
13
+ # in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18
+ # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19
+ # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21
+ # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+
23
+ require 'rubygems'
24
+ require 'hpricot'
25
+
26
+ module RBET
27
+
28
+ #
29
+ # usage:
30
+ #
31
+ # # First load the Tracker client
32
+ # tracker_client = ET::Tracker.new('username', 'password')
33
+ #
34
+ # # get job summary
35
+ # summary = job_client.retrieve_summary(12345) # pass a job_id
36
+ # => {'sentCount' => 163, 'deliveredCount' => 159, ... }
37
+ #
38
+ #
39
+ class Tracker < Client
40
+
41
+ def initialize(username,password,options={})
42
+ super
43
+ end
44
+
45
+ # retrieves tracking information for a particular job id
46
+ def retrieve_summary( job_id )
47
+ @job_id = job_id
48
+ response = send do|io|
49
+ io << render_template('tracker_retrieve_summary')
50
+ end
51
+ Error.check_response_error(response)
52
+ h = Hash.from_xml(response.read_body)
53
+ h['exacttarget']['system']['tracking']['emailSummary']
54
+ end
55
+
56
+ end
57
+ end
@@ -0,0 +1,8 @@
1
+ <system>
2
+ <system_name>tracking</system_name>
3
+ <action>retrieve</action>
4
+ <sub_action>summary</sub_action>
5
+ <search_type>jobID</search_type>
6
+ <search_value><%= @job_id %></search_value>
7
+ <search_value2></search_value2>
8
+ </system>
@@ -0,0 +1,60 @@
1
+ #
2
+ # Copyright (c) 2008 Shanti A. Braford
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included
13
+ # in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18
+ # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19
+ # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21
+ # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+
23
+ require 'rubygems'
24
+ require 'hpricot'
25
+
26
+ module RBET
27
+
28
+ #
29
+ # usage:
30
+ #
31
+ # # First load the Trigger client
32
+ # trigger = ET::TriggeredSend.new('username', 'password')
33
+ #
34
+ # # send message
35
+ # summary = trigger.deliver("someone@domain.org", "message-key", {:first_name => 'John', :last_name => 'Wayne'})
36
+ # => 0 # success
37
+ #
38
+ #
39
+ class TriggeredSend < Client
40
+
41
+ def initialize(username, password, options={})
42
+ super
43
+ end
44
+
45
+ # deliver triggered email
46
+ def deliver(email, external_key, attributes={} )
47
+ @email = email
48
+ @external_key = external_key
49
+ @attributes = attributes
50
+ raise "external_key can't be nil" unless @external_key
51
+ response = send do|io|
52
+ io << render_template('triggered_send')
53
+ end
54
+ Error.check_response_error(response)
55
+ doc = Hpricot.XML(response.read_body)
56
+ doc.at("triggered_send_description").inner_html.to_i
57
+ end
58
+
59
+ end
60
+ end
@@ -0,0 +1,21 @@
1
+ <system>
2
+ <system_name>triggeredsend</system_name>
3
+ <action>add</action>
4
+ <TriggeredSend xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
5
+ xmlns:xsd='http://www.w3.org/2001/XMLSchema'
6
+ xmlns='http://exacttarget.com/wsdl/partnerAPI'>
7
+ <TriggeredSendDefinition>
8
+ <CustomerKey><%= @external_key %></CustomerKey>
9
+ </TriggeredSendDefinition>
10
+ <Subscribers>
11
+ <SubscriberKey><%= @email %></SubscriberKey>
12
+ <EmailAddress><%= @email %></EmailAddress>
13
+ <% @attributes.each do |key, value| %>
14
+ <Attributes>
15
+ <Name><%= key %></Name>
16
+ <Value><%= value %></Value>
17
+ </Attributes>
18
+ <% end %>
19
+ </Subscribers>
20
+ </TriggeredSend>
21
+ </system>
@@ -0,0 +1,13 @@
1
+ module RBET
2
+ module Version
3
+
4
+ MAJOR = 1
5
+ MINOR = 0
6
+ TINY = 0
7
+
8
+ def self.to_s # :nodoc:
9
+ [MAJOR, MINOR, TINY].join('.')
10
+ end
11
+
12
+ end
13
+ end
@@ -0,0 +1,18 @@
1
+ require File.join(File.dirname(__FILE__),"help.rb")
2
+
3
+ class TestClient < Test::Unit::TestCase
4
+ include RBET::TestCase
5
+
6
+ def test_client_send_ping
7
+ client = RBET::Client.new('tester','tester11', {:service_url => 'http://127.0.0.1:9999/test/', :use_ssl => false})
8
+ result = client.send do|io|
9
+ io << %q(<system>
10
+ <system_name>diagnostics</system_name>
11
+ <action>Ping</action>
12
+ </system>)
13
+ end
14
+ assert_equal Net::HTTPOK, result.class
15
+ assert_match /<Ping>Running<\/Ping>/, result.body
16
+ end
17
+
18
+ end
@@ -0,0 +1,121 @@
1
+ require 'test/unit'
2
+ $:.unshift File.join(File.dirname(__FILE__), "..", "lib")
3
+ require 'rbet'
4
+ require 'webrick'
5
+ require 'thread'
6
+ require 'rubygems'
7
+ gem 'hpricot'
8
+ require 'hpricot'
9
+
10
+ # shut up, webrick :-)
11
+ class ::WEBrick::HTTPServer
12
+ def access_log(config, req, res)
13
+ # nop
14
+ end
15
+ end
16
+ class ::WEBrick::BasicLog
17
+ def log(level, data)
18
+ # nop
19
+ end
20
+ end
21
+
22
+ class RBETService
23
+ include RBET::Renderable
24
+ def initialize
25
+ set_template_path( File.join(File.dirname(__FILE__), "templates") )
26
+ end
27
+ end
28
+
29
+ class DiagnosticsService < RBETService
30
+ def ping(params)
31
+ render_template("diagnostics_ping_success")
32
+ end
33
+ end
34
+
35
+ class ListService < RBETService
36
+ def add(params)
37
+ list_type = params['list_type']
38
+ if list_type != 'private' and list_type != 'public'
39
+ render_template("list_add_failure")
40
+ else
41
+ render_template("list_add_success")
42
+ end
43
+ end
44
+
45
+ def retrieve(params)
46
+ render_template("list_retrieve_all_success")
47
+ end
48
+ end
49
+
50
+ class SubscriberService < RBETService
51
+
52
+ def retrieve(params)
53
+ if params['search_value2']
54
+ @email = params['search_value2']
55
+ render_template("subscriber_retrieve_success")
56
+ else
57
+ render_template("subscriber_retrieve_failed")
58
+ end
59
+ end
60
+
61
+ end
62
+
63
+ # list for subscriber requests and respond like ET would
64
+ class SubscriberRBETService < ::WEBrick::HTTPServlet::AbstractServlet
65
+
66
+ def do_POST(req, res)
67
+
68
+ xml_body = String.new(req.body)
69
+ xml_body.gsub!(/qf=xml&xml=/,'')
70
+ doc = Hpricot.XML(xml_body)
71
+ system = doc.at(:system)
72
+ system_name = system.at(:system_name).inner_html.strip.downcase
73
+ action = system.at(:action).inner_html.strip.downcase
74
+
75
+ params = {}
76
+ # load all the system parameters into a hash
77
+ system.each_child do|element|
78
+ next unless element.elem?
79
+ params[element.name] = element.inner_html.strip
80
+ end
81
+
82
+ response = service_for(system_name).send(action, params)
83
+
84
+ res.body = %Q(<?xml version="1.0" ?>
85
+ <exacttarget>
86
+ #{response}
87
+ </exacttarget>)
88
+
89
+ res['Content-Type'] = "text/xml"
90
+ end
91
+
92
+ private
93
+ def service_for(system_name)
94
+ eval("#{system_name.capitalize}Service.new") #render_template("#{system_name}_#{action}_success")
95
+ end
96
+
97
+ end
98
+
99
+ module RBET
100
+ module TestCase
101
+
102
+ def setup
103
+ # create the server
104
+ @server = WEBrick::HTTPServer.new({:BindAddress => "localhost", :Port => 9999})
105
+
106
+ # setup test server (simulates exact target)
107
+ @server.mount("/test/", SubscriberRBETService)
108
+
109
+ # start up the server in a background thread
110
+ @thread = Thread.new(@server) do|server|
111
+ server.start
112
+ end
113
+ end
114
+
115
+ def teardown
116
+ @server.shutdown
117
+ #@thread.join
118
+ end
119
+
120
+ end
121
+ end
@@ -0,0 +1,18 @@
1
+ require File.join(File.dirname(__FILE__),"help.rb")
2
+
3
+ class ListClient < Test::Unit::TestCase
4
+ include RBET::TestCase
5
+ def setup
6
+ super
7
+ @client = RBET::List.new('tester','tester11', :service_url => 'http://127.0.0.1:9999/test/', :use_ssl => false, :debug_output => $stderr)
8
+ end
9
+
10
+ def test_list_all
11
+ @client.all
12
+ end
13
+
14
+ def test_list_add
15
+ @client.add('sample list')
16
+ end
17
+
18
+ end
@@ -0,0 +1,18 @@
1
+ require File.join(File.dirname(__FILE__),"help.rb")
2
+
3
+ class SubscriberClient < Test::Unit::TestCase
4
+ include RBET::TestCase
5
+
6
+ def test_subscriber_load
7
+ client = RBET::Subscriber.new('tester', 'tester11', :service_url => 'http://127.0.0.1:9999/test/', :use_ssl => false)
8
+ client.load!('jdoe@email.com')
9
+ assert_equal 'jdoe@email.com', client.attrs['Email Address']
10
+ assert_equal 'John', client.attrs['First Name']
11
+ assert_equal 'Doe', client.attrs['Last Name']
12
+ assert_equal "", client.attrs['Title']
13
+ assert_equal nil, client.attrs['Not Event Defined']
14
+ assert_equal 'jdoe@email.com', client.email
15
+ assert_equal 'Active', client.status
16
+ end
17
+
18
+ end
@@ -0,0 +1,5 @@
1
+ <system>
2
+ <diagnostics>
3
+ <Ping>Running</Ping>
4
+ </diagnostics>
5
+ </system>)
@@ -0,0 +1,6 @@
1
+ <?xml version='1.0'?>
2
+ <exacttarget>
3
+ <system>
4
+ <list><error>93</error><error_description>You did not specify a valid list type.</error_description></list>
5
+ </system>
6
+ </exacttarget>
@@ -0,0 +1,9 @@
1
+ <?xml version="1.0" ?>
2
+ <exacttarget>
3
+ <system>
4
+ <list>
5
+ <list_info>List was added successfully</list_info>
6
+ <list_description>80080</list_description>
7
+ </list>
8
+ </system>
9
+ </exacttarget>
@@ -0,0 +1,12 @@
1
+ <?xml version="1.0" ?>
2
+ <exacttarget>
3
+ <system>
4
+ <list>
5
+ <listid>12345</listid>
6
+ <listid>67890</listid>
7
+ <listid>80080</listid>
8
+ <listid>80081</listid>
9
+ <listid>80082</listid>
10
+ </list>
11
+ </system>
12
+ </exacttarget>
@@ -0,0 +1,15 @@
1
+ <?xml version="1.0" ?>
2
+ <exacttarget>
3
+ <system>
4
+ <list>
5
+ <list_name>API-API Test List</list_name>
6
+ <list_type>Public</list_type>
7
+ <modified>8/18/2003 10:11:59 AM</modified>
8
+ <subscriber_count>129</subscriber_count>
9
+ <active_total>126</active_total>
10
+ <held_count>1</held_count>
11
+ <bounce_count>2</bounce_count>
12
+ <unsub_count>0</unsub_count>
13
+ </list>
14
+ </system>
15
+ </exacttarget>
@@ -0,0 +1,6 @@
1
+ <system>
2
+ <subscriber>
3
+ <subscriber_info>Subscriber was added/updated successfully</subscriber_info>
4
+ <subscriber_description>12334566</subscriber_description>
5
+ </subscriber>
6
+ </system>
@@ -0,0 +1,9 @@
1
+ <?xml version='1.0'?>
2
+ <exacttarget>
3
+ <system>
4
+ <subscriber>
5
+ <error>1</error>
6
+ <error_description>Subscriber not found with ListID = <%= @listid %> Email Address = <%= @email %></error_description>
7
+ </subscriber>
8
+ </system>
9
+ </exacttarget>
@@ -0,0 +1,15 @@
1
+ <system>
2
+ <subscriber>
3
+ <subid>125704849</subid>
4
+ <listid>63718</listid>
5
+ <list_name>Newsletter List</list_name>
6
+ <Email__Address><%= @email %></Email__Address>
7
+ <Status>Active</Status>
8
+ <Email__Type>HTML</Email__Type>
9
+ <First__Name>John</First__Name>
10
+ <Last__Name>Doe</Last__Name>
11
+ <Title />
12
+ <Region />
13
+ <showChannelID>123456</showChannelID>
14
+ </subscriber>
15
+ </system>
metadata ADDED
@@ -0,0 +1,92 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rbet
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - See Contributing Section
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-01-30 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description:
17
+ email: kevin@conceptsahead.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README.rdoc
24
+ files:
25
+ - README.rdoc
26
+ - Rakefile
27
+ - lib/rbet/auth.rxml
28
+ - lib/rbet/client.rb
29
+ - lib/rbet/error.rb
30
+ - lib/rbet/list.rb
31
+ - lib/rbet/list_add.rxml
32
+ - lib/rbet/list_list_all.rxml
33
+ - lib/rbet/list_retrieve.rxml
34
+ - lib/rbet/list_retrieve_subscribers.rxml
35
+ - lib/rbet/list_send_email.rxml
36
+ - lib/rbet/ping.rxml
37
+ - lib/rbet/renderable.rb
38
+ - lib/rbet/subscriber.rb
39
+ - lib/rbet/subscriber_add.rxml
40
+ - lib/rbet/subscriber_delete.rxml
41
+ - lib/rbet/subscriber_retrieve.rxml
42
+ - lib/rbet/subscriber_retrieve_by_id.rxml
43
+ - lib/rbet/subscriber_update.rxml
44
+ - lib/rbet/tracker.rb
45
+ - lib/rbet/tracker_retrieve_summary.rxml
46
+ - lib/rbet/triggered_send.rb
47
+ - lib/rbet/triggered_send.rxml
48
+ - lib/rbet/version.rb
49
+ - lib/rbet.rb
50
+ - test/client_test.rb
51
+ - test/help.rb
52
+ - test/list_test.rb
53
+ - test/subscriber_test.rb
54
+ - test/templates/diagnostics_ping_success.rxml
55
+ - test/templates/list_add_failure.rxml
56
+ - test/templates/list_add_success.rxml
57
+ - test/templates/list_retrieve_all_success.rxml
58
+ - test/templates/list_retrieve_bylistid_success.rxml
59
+ - test/templates/subscriber_add_success.rxml
60
+ - test/templates/subscriber_retrieve_failed.rxml
61
+ - test/templates/subscriber_retrieve_success.rxml
62
+ has_rdoc: true
63
+ homepage: http://github.com/n3bulous/rbet
64
+ licenses: []
65
+
66
+ post_install_message:
67
+ rdoc_options:
68
+ - --main
69
+ - README.rdoc
70
+ require_paths:
71
+ - lib
72
+ required_ruby_version: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: "0"
77
+ version:
78
+ required_rubygems_version: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: "0"
83
+ version:
84
+ requirements: []
85
+
86
+ rubyforge_project:
87
+ rubygems_version: 1.3.5
88
+ signing_key:
89
+ specification_version: 3
90
+ summary: A ruby wrapper for the Exact Target API
91
+ test_files: []
92
+