campaigning 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.bnsignore ADDED
@@ -0,0 +1,16 @@
1
+ # The list of files that should be ignored by Mr Bones.
2
+ # Lines that start with '#' are comments.
3
+ #
4
+ # A .gitignore file can be used instead by setting it as the ignore
5
+ # file in your Rakefile:
6
+ #
7
+ # PROJ.ignore_file = '.gitignore'
8
+ #
9
+ # For a project with a C extension, the following would be a good set of
10
+ # exclude patterns (uncomment them if you want to use them):
11
+ # *.[oa]
12
+ # *~
13
+ announcement.txt
14
+ coverage
15
+ doc
16
+ pkg
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.sw?
2
+ .DS_Store
3
+ coverage
4
+ rdoc
5
+ pkg
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Marcelo Menezes
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,65 @@
1
+ = Campaigning
2
+
3
+ This is a Ruby wrapper around CampaignMonitor API(www.campaignmonitor.com/api) using SOAP.
4
+
5
+
6
+ == Pre-requisites
7
+ An account with Campaign Monitor and the API Key (www.campaignmonitor.com).
8
+
9
+
10
+ == Resources
11
+
12
+ === Dependencies
13
+
14
+ This gem requires the following gems:
15
+
16
+ Soap4r (1.5.8)
17
+
18
+ Jeweler (http://technicalpickles.com/posts/craft-the-perfect-gem-with-jeweler)
19
+
20
+ === Installing
21
+
22
+ sudo gem install gnumarcelo-campaigning -s http://gems.github.com
23
+
24
+
25
+ === Configuring your API key
26
+ require 'campaigning'
27
+ CAMPAIGN_MONITOR_API_KEY = '_put_here_your_api_key_'
28
+
29
+
30
+ == Usage
31
+
32
+ This gem provides a set of classes to access all available information on Campaign Monitor.
33
+
34
+ These are the list of classes:
35
+
36
+ Campaigning, Campaigning::Client, Campaigning::Campaign, Campaigning::List and Campaigning::Subscriber
37
+
38
+ The examples below assumes you have set *CAMPAIGN_MONITOR_API_KEY* constant with your Campaign monitor API.
39
+
40
+ Sample use of the Client class:
41
+
42
+ #Here is how to get a list of all clients...
43
+ clients = Campaigning::Client.get_all_clients
44
+
45
+
46
+ #Here is how to create a brand new subscriber list for an Client
47
+ client = Campaigning::Client.find_by_name("Client One Company")
48
+ list = Campaigning::List.create!(
49
+ :clientID => client.clientID,
50
+ :title => "List of people from Brazil",
51
+ :confirmOptIn => false
52
+ )
53
+
54
+ For further examples please check at the *sample* directory.
55
+
56
+
57
+ == What if I found a BUG?
58
+
59
+ If you found a bug in the Campaigning wrapper, it's easy to report it on the like below:
60
+ http://github.com/gnumarcelo/campaigning/issues
61
+
62
+
63
+ == Copyright
64
+
65
+ Copyright (c) 2009 Marcelo Menezes. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,59 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "campaigning"
8
+ gem.summary = %Q{TODO}
9
+ gem.email = "gnumarcelo@gmail.com"
10
+ gem.homepage = "http://github.com/gnumarcelo/campaigning"
11
+ gem.authors = ["Marcelo Menezes"]
12
+ gem.add_dependency('soap4r', '~> 1.5.0')
13
+
14
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
15
+ end
16
+ rescue LoadError
17
+ puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
18
+ end
19
+
20
+ require 'rake/testtask'
21
+ Rake::TestTask.new(:test) do |test|
22
+ test.libs << 'lib' << 'test'
23
+ test.pattern = 'test/**/*_test.rb'
24
+ test.verbose = true
25
+ end
26
+
27
+ begin
28
+ require 'rcov/rcovtask'
29
+ Rcov::RcovTask.new do |test|
30
+ test.libs << 'test'
31
+ test.pattern = 'test/**/*_test.rb'
32
+ test.verbose = true
33
+ end
34
+ rescue LoadError
35
+ task :rcov do
36
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
37
+ end
38
+ end
39
+
40
+
41
+ task :default => :test
42
+
43
+ require 'rake/rdoctask'
44
+ Rake::RDocTask.new do |rdoc|
45
+ if File.exist?('VERSION.yml')
46
+ config = YAML.load(File.read('VERSION.yml'))
47
+ version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
48
+ else
49
+ version = ""
50
+ end
51
+
52
+ rdoc.rdoc_dir = 'rdoc'
53
+ rdoc.title = "campaigning #{version}"
54
+ rdoc.rdoc_files.include('README*')
55
+ rdoc.rdoc_files.include('lib/**/*.rb')
56
+ rdoc.rdoc_files.exclude('lib/campaigning/soap/generated/*.rb')
57
+ rdoc.options << "--inline-source"
58
+ end
59
+
data/VERSION.yml ADDED
@@ -0,0 +1,4 @@
1
+ ---
2
+ :major: 0
3
+ :minor: 15
4
+ :patch: 0
@@ -0,0 +1,77 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{campaigning}
8
+ s.version = "0.15.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Marcelo Menezes"]
12
+ s.date = %q{2009-11-30}
13
+ s.email = %q{gnumarcelo@gmail.com}
14
+ s.extra_rdoc_files = [
15
+ "LICENSE",
16
+ "README.rdoc"
17
+ ]
18
+ s.files = [
19
+ ".bnsignore",
20
+ ".gitignore",
21
+ "LICENSE",
22
+ "README.rdoc",
23
+ "Rakefile",
24
+ "VERSION.yml",
25
+ "campaigning.gemspec",
26
+ "lib/campaigning.rb",
27
+ "lib/campaigning/campaign.rb",
28
+ "lib/campaigning/campaigning.rb",
29
+ "lib/campaigning/client.rb",
30
+ "lib/campaigning/list.rb",
31
+ "lib/campaigning/module_mixin.rb",
32
+ "lib/campaigning/soap/generated/default.rb",
33
+ "lib/campaigning/soap/generated/defaultDriver.rb",
34
+ "lib/campaigning/soap/generated/defaultMappingRegistry.rb",
35
+ "lib/campaigning/subscriber.rb",
36
+ "lib/campaigning/template.rb",
37
+ "sample/campaign_sample.rb",
38
+ "sample/campaigning_sample.rb",
39
+ "sample/client_sample.rb",
40
+ "sample/list_sample.rb",
41
+ "sample/subscriber_sample.rb",
42
+ "test/campaign_test.rb",
43
+ "test/campaigning_test.rb",
44
+ "test/client_test.rb",
45
+ "test/list_test.rb",
46
+ "test/subscriber_test.rb",
47
+ "test/template_test.rb",
48
+ "test/test_helper.rb"
49
+ ]
50
+ s.homepage = %q{http://github.com/gnumarcelo/campaigning}
51
+ s.rdoc_options = ["--charset=UTF-8"]
52
+ s.require_paths = ["lib"]
53
+ s.rubygems_version = %q{1.3.5}
54
+ s.summary = %q{Interfaces with the campaign monitor api}
55
+ s.test_files = [
56
+ "test/campaign_test.rb",
57
+ "test/campaigning_test.rb",
58
+ "test/client_test.rb",
59
+ "test/list_test.rb",
60
+ "test/subscriber_test.rb",
61
+ "test/template_test.rb",
62
+ "test/test_helper.rb"
63
+ ]
64
+
65
+ if s.respond_to? :specification_version then
66
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
67
+ s.specification_version = 3
68
+
69
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
70
+ s.add_runtime_dependency(%q<soap4r>, ["~> 1.5.0"])
71
+ else
72
+ s.add_dependency(%q<soap4r>, ["~> 1.5.0"])
73
+ end
74
+ else
75
+ s.add_dependency(%q<soap4r>, ["~> 1.5.0"])
76
+ end
77
+ end
@@ -0,0 +1 @@
1
+ require File.dirname(__FILE__) + '/campaigning/campaigning'
@@ -0,0 +1,218 @@
1
+ # Campaign is defined in soap/default.rb which is automatically generated.
2
+ # In this file we add additional methods to the Campaign class.
3
+ require File.expand_path(File.dirname(__FILE__)) + '/module_mixin'
4
+
5
+
6
+ module Campaigning
7
+ class Campaign
8
+ include ModuleMixin
9
+ attr_accessor :campaignID
10
+ attr_accessor :subject
11
+ attr_accessor :name
12
+ attr_accessor :sentDate
13
+ attr_accessor :totalRecipients
14
+
15
+ def initialize(campaignID = nil, subject = nil, name = nil, sentDate = nil, totalRecipients = nil, opts={})
16
+ @apiKey = opts[:apiKey] || CAMPAIGN_MONITOR_API_KEY
17
+ @campaignID = campaignID
18
+ @subject = subject
19
+ @name = name
20
+ @sentDate = sentDate
21
+ @totalRecipients = totalRecipients
22
+ end
23
+
24
+ #Creates a campaign for an existing client. This campaign will be imported and ready to send to the subscribers in
25
+ #the specified lists and segments.
26
+ #The campaign must have both HTML and plain text content, imported from the internet. Styling for the HTML content
27
+ #will be automatically brought inline.
28
+ #
29
+ #Available _params_ argument are:
30
+ # * :clientID - The ID of the Client you want to create a campaign
31
+ # * :campaignName - The name of the new campaign. This must be unique across all draft campaigns for the client.
32
+ # * :campaignSubject - The subject of the new campaign.
33
+ # * :fromName - The name to appear in the From field in the recipients email client when they receive the new campaign.
34
+ # * :fromEmail - The email address that the new campaign will come from.
35
+ # * :replyTo - The email address that any replies to the new campaign will be sent to.
36
+ # * :htmlUrl - The URL of the HTML content for the new campaign. If no unsubscribe link is found then one will be added automatically. Styling in
37
+ # the campaign will be automatically brought inline. If your URL has querystring values, you will need to encode them.
38
+ # * :textUrl - The URL of the Text content for the new campaign. If no unsubscribe link is found then one will be added automatically.
39
+ # * :subscriberListIDs - An array of lists to send the campaign to. See http://www.campaignmonitor.com/api/required/#listid for more details.
40
+ # * :listSegments - An array of Segment Names and their appropriate List ID s to send the campaign to.
41
+ # * :apiKey - optional API key to use to make request. Will use CAMPAIGN_MONITOR_API_KEY if not set.
42
+ #
43
+ #*Return*:
44
+ #
45
+ #*Success*: Upon a successful call, this method will return a Campaigning::Campaign object which was recently created.
46
+ #
47
+ #*Error*: An Exception containing the cause of the error will be raised.
48
+ def self.create!(params)
49
+ response = @@soap.createCampaign(
50
+ :apiKey => params[:apiKey] || CAMPAIGN_MONITOR_API_KEY,
51
+ :clientID => params[:clientID],
52
+ :campaignName => params[:campaignName],
53
+ :campaignSubject => params[:campaignSubject],
54
+ :fromName => params[:fromName],
55
+ :fromEmail => params[:fromEmail],
56
+ :replyTo => params[:replyTo],
57
+ :htmlUrl => params[:htmlUrl],
58
+ :textUrl => params[:textUrl],
59
+ :subscriberListIDs => params[:subscriberListIDs],
60
+ :listSegments => params[:listSegments]
61
+ )
62
+
63
+ campaign_id = handle_response response.campaign_CreateResult
64
+ Campaign.new( campaign_id, nil, params[:campaignName], nil, nil, :apiKey=> (params[:apiKey] || CAMPAIGN_MONITOR_API_KEY) )
65
+ end
66
+
67
+ #Deletes an existing campaign.
68
+ #
69
+ #*Return*:
70
+ #
71
+ #*Success*: Upon a successful call, this method will return a Campaigning::Result object wich consists of a +code+ and +message+ fields
72
+ #containing a successful message.
73
+ #
74
+ #*Error*: An Exception containing the cause of the error will be raised.
75
+ def delete!
76
+ Campaign.delete!(@campaignID, :apiKey=> @apiKey)
77
+ self.campaignID, self.subject, self.sentDate, self.totalRecipients = nil, nil, nil, nil
78
+ end
79
+
80
+ #Deletes an existing campaign.
81
+ #
82
+ #Available _opts_ argument are:
83
+ # * :apiKey - optional API key to use to make request. Will use CAMPAIGN_MONITOR_API_KEY if not set.
84
+ #
85
+ #*Return*:
86
+ #
87
+ #*Success*: Upon a successful call, this method will return a Campaigning::Result object wich consists of a +code+ and +message+ fields
88
+ #containing a successful message.
89
+ #
90
+ #*Error*: An Exception containing the cause of the error will be raised.
91
+ def self.delete!(campaign_id, opts={})
92
+ response = @@soap.deleteCampaign(:apiKey => opts[:apiKey] || CAMPAIGN_MONITOR_API_KEY, :campaignID => campaign_id)
93
+ handle_response response.campaign_DeleteResult
94
+ end
95
+
96
+ #Gets a list of all subscribers who bounced for a given campaign, and the type of bounce (H=Hard Bounce, S=Soft Bounce).
97
+ #
98
+ #*Return*:
99
+ #
100
+ #*Success*: Upon a successful call, this method will return a collection of <code>SubscriberBounce</code> objects, each of
101
+ #which consists of the subscribers <code>:emailAddress</code>, the <code>listID</code> they belong to, and the <code>bounceType</code>
102
+ #of bounce they experienced, whether hard or soft.
103
+ #
104
+ #*Error*: An Exception containing the cause of the error will be raised.
105
+ def bounces
106
+ response = @@soap.getCampaignBounces(:apiKey => @apiKey, :campaignID => @campaignID )
107
+ handle_response response.campaign_GetBouncesResult
108
+ end
109
+
110
+ #Returns an array of Campaigning::List objects that a given campaign was sent to.
111
+ #
112
+ #*Return*:
113
+ #
114
+ #*Success*: Upon a successful call, this method will return a collection of Campaigning::List object.
115
+ #
116
+ #*Error*: An Exception containing the cause of the error will be raised.
117
+ def lists
118
+ response = @@soap.getCampaignLists(:apiKey => @apiKey, :campaignID => @campaignID )
119
+ lists = handle_response response.campaign_GetListsResult
120
+ lists.collect do |list|
121
+ List.new(list.listID, list.name, :apiKey=> @apiKey)
122
+ end
123
+ end
124
+
125
+ #Gets a list of all subscribers who opened a given campaign, and the number of times they opened the campaign.
126
+ #
127
+ #*Return*:
128
+ #
129
+ #*Success*: Upon a successful call, this method will return a collection of <code>SubscriberOpen</code> objects, each of
130
+ #which consists of the subscribers <code>:emailAddress</code>, the <code>listID</code> they belong to, and the <code>numberOfOpens</code>
131
+ #representing the number of times they opened the given campaign.
132
+ #
133
+ #*Error*: An Exception containing the cause of the error will be raised.
134
+ def opens
135
+ response = @@soap.getCampaignOpens(:apiKey => @apiKey, :campaignID => @campaignID )
136
+ handle_response response.campaign_GetOpensResult
137
+ end
138
+
139
+ #Gets a list of all subscribers who clicked a link for a given campaign, the ID of the list they belong to,
140
+ #the links they clicked, and the number of times they clicked the link.
141
+ #
142
+ #Example of usage:
143
+ #
144
+ # campaign_obj.subscriber_clicks.each do |subscriber|
145
+ # puts "Subscriber: #{subscriber.emailAddress}"
146
+ # subscriber.clickedLinks.each do |clicked|
147
+ # puts "Clicked link: #{clicked.link} - Number of clicks: #{clicked.clicks}"
148
+ # end
149
+ # end
150
+ #
151
+ #
152
+ #*Return*:
153
+ #
154
+ #*Success*: Upon a successful call, this method will return a collection of <code>SubscriberClick</code> objects, each of which consists of
155
+ #the subscribers <code>emailAddress</code>, the <code>listID</code> representing list they belong to, and the <code>clickedLinks</code>array
156
+ #representing the links they have clicked and the number of times they clicked each link.
157
+ #
158
+ #*Error*: An Exception containing the cause of the error will be raised.
159
+ def subscriber_clicks
160
+ response = @@soap.getSubscriberClicks(:apiKey => @apiKey, :campaignID => @campaignID )
161
+ handle_response response.campaign_GetSubscriberClicksResult
162
+ end
163
+
164
+ #Gets a statistical summary, including number of recipients and open count, for a given campaign.
165
+ #
166
+ #*Return*:
167
+ #
168
+ #*Success*: Upon a successful call, this method will return summary statistical values about this particular campaign
169
+ #including the number of recipients, the number of total opens, the number of link clicks, the number of recipients
170
+ #who unsubscribed and the number who bounced.
171
+ #
172
+ #*Error*: An Exception containing the cause of the error will be raised.
173
+ def summary
174
+ response = @@soap.getCampaignSummary(:apiKey => @apiKey, :campaignID => @campaignID )
175
+ handle_response response.campaign_GetSummaryResult
176
+ end
177
+
178
+ #Gets a list of all subscribers who unsubscribed for a given campaign.
179
+ #
180
+ #*Return*:
181
+ #
182
+ #*Success*: Upon a successful call, this method will return a collection of SubscriberUnsubscribe objects, each of which consists
183
+ #of the <code>emailAddress</code> representing subscribers email address and the <code>listID</code> representing the list they belong to.
184
+ #
185
+ #*Error*: An Exception containing the cause of the error will be raised.
186
+ def unsubscribes
187
+ response = @@soap.getCampaignUnsubscribes(:apiKey => @apiKey, :campaignID => @campaignID )
188
+ handle_response response.campaign_GetUnsubscribesResult
189
+ end
190
+
191
+ #Schedules an existing campaign for sending.
192
+ #
193
+ #The campaign must be imported with defined recipients. For campaigns with more than 5 recipients the user must have
194
+ #sufficient credits or their credit card details saved within the application for the campaign to be sent via the API.
195
+ #For campaigns with 5 recipients or less the user must have enough test campaigns remaining in their API account.
196
+ #For further information about credits for campaigns please check at: http://www.campaignmonitor.com/api/method/campaign-send/
197
+ #
198
+ #Available _params_ argument are:
199
+ # * :confirmationEmail - The email address that the confirmation email that the campaign has been sent will go to.
200
+ # * :sendDate - The date the campaign should be scheduled to be sent. To send a campaign immediately pass in "Immediately".
201
+ # This date should be in the users timezone and formatted as YYYY-MM-DD HH:MM:SS.
202
+ #
203
+ #*Return*:
204
+ #Upon a successful call, this method will return a Result object with the newly create Campaign's ID as the Code.
205
+ #
206
+ #*Error*: An Exception containing the cause of the error will be raised.
207
+ def send!(params)
208
+ response = @@soap.sendCampaign(
209
+ :apiKey => @apiKey,
210
+ :campaignID => @campaignID,
211
+ :confirmationEmail => params[:confirmationEmail],
212
+ :sendDate => params[:sendDate]
213
+ )
214
+ handle_response response.campaign_SendResult
215
+ end
216
+
217
+ end
218
+ end