hominid 2.0.1 → 2.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,136 +1,92 @@
1
1
  h1. Hominid
2
2
 
3
- Hominid is a Ruby gem that provides a wrapper for interacting with the "Mailchimp":http://www.mailchimp.com email marketing service API ("version 1.2":http://www.mailchimp.com/api/1.2/).
3
+ Hominid is a Ruby gem that provides a wrapper for interacting with the "Mailchimp":http://eepurl.com/ew8J email marketing service API ("version 1.2":http://www.mailchimp.com/api/1.2/).
4
4
 
5
5
  h2. Installation
6
6
 
7
- <pre><code>sudo gem install hominid, :version => '>= 2.0.1', :source => "http://gemcutter.org"</code></pre>
7
+ <pre><code>sudo gem install hominid</code></pre>
8
8
 
9
9
  Hominid is hosted at "Gemcutter":http://gemcutter.org. Be sure that you have the Gemcutter gem installed if you are having trouble installing Hominid:
10
10
 
11
- <pre><code>sudo gem install gemcutter
12
- gem tumble</code></pre>
11
+ <pre><code>sudo gem install gemcutter</code></pre>
13
12
 
14
- h2. Configuration
13
+ h2. Requirements
15
14
 
16
- You will need to create a "Mailchimp":http://www.mailchimp.com/signup account and get your API key (available at http://admin.mailchimp.com/account/api/) in order to get started.
17
-
18
- If you are using Hominid inside a Rails application, you can create a config file at @/config/hominid.yml@ with your Mailchimp account information and basic configuration options:
19
-
20
- <pre><code>development:
21
- username: USERNAME
22
- password: PASSWORD
23
- api_key: API KEY
24
- send_goodbye: false
25
- send_notify: false
26
- double_opt: false
27
-
28
- ...</code></pre>
29
-
30
- Run @rake hominid:config@ from within a Rails app to create an empty config file.
31
- Note: You will need to <pre><code>require 'hominid'</code></pre> in your @Rakefile@ to make this rake task available to your application.
15
+ You will need a "Mailchimp":http://eepurl.com/ew8J account. Once you have your Mailchimp account set up, you will need to "generate an API key":http://admin.mailchimp.com/account/api/ in order to get started using Hominid.
32
16
 
33
17
  h2. Usage
34
18
 
35
- Not all API methods are supported (yet). Currently there are classes for working with lists (_Hominid::List_), campaigns (_Hominid::Campaign_) and accessing the helper methods (_Hominid::Helper_).
36
-
37
- h3. Working with Lists
38
-
39
- The _Hominid::List_ class is available for working finding lists and working with particular lists. See _Hominid::List_ for more information.
40
-
41
- h4. List Finder Methods
19
+ Hominid is intended to be a complete Ruby wrapper for working with the Mailchimp API. As of release 2.0.2, all methods available from the Mailchimp API (Version 1.2) are available. Please note in order to use some methods you will need to have "A.I.M. Reports":https://admin.mailchimp.com/account/addons installed on your Mailchimp account.
42
20
 
43
- There are finder methods for working with lists. Refer to _Hominid::List_ to see the other finders availables.
21
+ You will need to pass your Mailchimp API key to get started:
44
22
 
45
- <pre><code>lists = Hominid::List.all</code></pre>
23
+ <pre><code>h = Hominid::Base.new({:api_key => API_KEY})</code></pre>
46
24
 
47
- <pre><code>list = Hominid::List.find_by_name("List Name")</code></pre>
25
+ You can also pass in any other config options that you would like to change from the defaults. Take a look at @Hominid::Base@ to see what the default values are.
48
26
 
49
- <pre><code>list = Hominid::List.find(id_or_web_id)</code></pre>
27
+ Once you have created a Hominid object, you can begin interacting with the Mailchimp account that your API key is associated with.
50
28
 
51
- h4. Subscribing
52
-
53
- To subscribe a person or persons to a Mailchimp list:
54
-
55
- <pre><code>list.subscribe("sample@emailaddress.com")</code></pre>
29
+ h3. Working with Lists
56
30
 
57
- <pre><code>list.subscribe_many([{:EMAIL => 'sample@emailaddress.com', :EMAIL_TYPE => 'html'}, {:EMAIL => 'another@emailaddress.com', :EMAIL_TYPE => 'html'}])</code></pre>
31
+ We have provided some finder methods to make working with your mailing lists easier:
58
32
 
59
- h4. Unsubscribing
33
+ <pre><code>lists = h.lists
34
+ list = h.find_list_by_name("Mailing List Name")
35
+ list = h.find_list_by_id("List ID")
36
+ list = h.find_list_by_web_id("List Web ID")</code></pre>
60
37
 
61
- To unsubscribe a person or persons from a Mailchimp list:
38
+ There are also finders for easily getting at List ID's, which are required for nearly all the list methods:
62
39
 
63
- <pre><code>list.unsubscribe("sample@emailaddress.com")</code></pre>
40
+ <pre><code>list_id = h.find_list_id_by_name("Mailing List Name")
41
+ list_id_ = h.find_list_id_by_web_id("List Web ID")</code></pre>
64
42
 
65
- <pre><code>list.unsubscribe_many(['sample@emailaddress.com', 'another@emailaddress.com'])</code></pre>
43
+ This means that you can _(for example)_ subscribe someone to a particular mailing list:
66
44
 
67
- h4. Updating
45
+ <pre><code>h.subscribe(h.find_list_id_by_name("Mailing List Name"), "email@domain.com", {:FNAME => "Bob", :LNAME => "Smith"}, {:email_type => 'html'})</code></pre>
68
46
 
69
- In the following example, we will be changing a person's email address on the Mailchimp list from @sample@ to @another@:
47
+ Or to update a subscriber to a particular list:
70
48
 
71
- <pre><code>list.update_member('sample@emailaddress.com', {:EMAIL => 'another@emailaddress.com'}, 'html')</code></pre>
49
+ <pre><code>h.update_member(h.find_list_id_by_name("Mailing List Name"), "old_email@domain.com", {:EMAIL => "new_email_@domain.com"}, 'html')</code></pre>
72
50
 
73
- You can also updated other attributes by including the MERGE_VARS that you want to change, such as @EMAIL@, @FNAME@, @LNAME@ and @INTERESTS@. Get a list of merge tags for a particular list by running @list.merge_tags@.
51
+ Take a look at @Hominid::List@ to see the methods that are available for interacting with your lists.
74
52
 
75
53
  h3. Working with Campaigns
76
54
 
77
- The _Hominid::Campaign_ class provides methods for working with a campaigns.
78
-
79
- h4. Campaign Finder Methods
55
+ We have provided some finder methods to make working with your campaigns easier:
80
56
 
81
- There are finder methods for campaigns as well. Refer to _Hominid::Campaign_ to see the other finders available.
57
+ <pre><code>campaigns = h.campaigns
58
+ campaigns = h.find_campaigns_by_list_name("Mailing List Name")
59
+ campaigns = h.find_campaigns_by_list_id("Mailing List ID")
60
+ campaigns = h.find_campaigns_by_type("regular")
61
+ campaign = h.find_campaign_by_id("Campaign ID")
62
+ campaign = h.find_campaign_by_title("Campaign Title")</code></pre>
82
63
 
83
- <pre><code>campaigns = Hominid::Campaign.all</code></pre>
64
+ To create a new campaign, use the @create_campaign@ method:
84
65
 
85
- <pre><code>campaigns = Hominid::Campaign.find_by_list_name("List Name")</code></pre>
66
+ <pre><code>new_campaign = h.create_campaign(...)</code></pre>
86
67
 
87
- h4. Creating a Campaign
68
+ Take a look at @Hominid::Campaign@ to see the methods that are available for interacting with your campaigns.
88
69
 
89
- You can create new campaigns using Hominid as well. Please refer to the documentation in _Hominid::Base_ for more information about the options available when creating a new campaign.
70
+ h3. Mailchimp Helper Methods
90
71
 
91
- <pre><code>new_campaign = Hominid::Campaign.create('regular', options, content, segment_opts, type_opts)</code></pre>
72
+ There are a series of helper methods that are also made available with the Hominid gem. For example, to retrieve information about the Mailchimp account associated with your API key, simply:
92
73
 
93
- h4. Schedule a Campaign
74
+ <pre><code>account_details_ = h.account_details</code></pre>
94
75
 
95
- As an example of how to work with a particular campaign, use the _Hominid::Campaign_ class. Extending from the previous example, since the _#create_campaign_ method returns the ID of the created campaign, we can use it to instantiate the _Hominid::Campaign_ class and schedule our new campaign to go be delivered 2 days from now:
76
+ In this case, the @account_details@ object can be accessed like:
96
77
 
97
- <pre><code>campaign = Hominid::Campaign.new(:id => new_campaign)</code></pre>
78
+ <pre><code>account_details.contact.company
79
+ account_details.orders</code></pre>
98
80
 
99
- <pre><code>campaign.schedule_campaign(2.days.from_now)</code></pre>
81
+ Take a look at @Hominid::Helper@ to see the helper methods that are available.
100
82
 
101
- h3. Helper Methods
83
+ h3. Mailchimp Security Methods
102
84
 
103
- The _Hominid::Helper_ class provides a way to access the helper methods for the Mailchimp API. For example, to create a new folder for filing campaigns:
85
+ There are a couple of security methods that are also made available with the Hominid gem. These are primarily used for dealing with API keys, and require your Mailchimp account username and password:
104
86
 
105
- <pre><code>folder = Hominid::Helper.create_folder("Folder Name")</code></pre>
87
+ <pre><code>h.api_keys('username', 'password')</code></pre>
106
88
 
107
- h2. Syncing Your Application
108
-
109
- If you are integrating an application with Mailchimp, Hominid will provide a way for your app to connect with your Mailchimp account. However, it does not provide a way for Mailchimp to connect to your application, which is why Mailchimp has implemented "web hooks":http://www.mailchimp.com/api/webhooks/.
110
-
111
- The _Hominid::Webhook_ class helps with receiving <tt>POST</tt> data from a Mailchimp webhook:
112
-
113
- <pre><code>hook = Hominid::Webhook.new(params)
114
- case hook.event
115
- when "subscribe"
116
- user = User.find_by_email(hook.email)
117
- user.opted_in = true
118
- user.save
119
- when "unsubscribe"
120
- user = User.find_by_email(hook.email)
121
- user.opted_in = false
122
- user.save
123
- when "profile"
124
- user = User.find_by_email(hook.email)
125
- user.first_name = hook.first_name
126
- user.last_name = hook.last_name
127
- user.email_type = hook.email_type
128
- user.save
129
- when "upemail"
130
- user = User.find_by_email(hook.old_email)
131
- user.email = hook.new_email
132
- user.save
133
- end</code></pre>
89
+ Take a look at @Hominid::Security@ to see the security methods that are available.
134
90
 
135
91
  h2. Contributors
136
92
 
@@ -146,6 +102,8 @@ Hominid is maintained by "Brian Getting":http://terra-firma-design.com. A very s
146
102
  * "Matthew Carlson":http://mandarinsoda.com/
147
103
  * "Kelly Mahan":http://digimedia.com/
148
104
  * "C.G. Brown":http://www.projectlocker.com/
105
+ * "Bill Abney":http://github.com/babney
106
+ * "David Rice":http://github.com/davidjrice
149
107
 
150
108
  h2. Note on Patches/Pull Requests
151
109
 
@@ -157,5 +115,4 @@ h2. Note on Patches/Pull Requests
157
115
 
158
116
  h2. Copyright
159
117
 
160
- Copyright (c) 2009 Brian Getting. See LICENSE for details.
161
-
118
+ Copyright (c) 2009 Brian Getting. See LICENSE for details.
data/Rakefile CHANGED
@@ -10,7 +10,6 @@ begin
10
10
  gem.email = "brian@terra-firma-design.com"
11
11
  gem.homepage = "http://github.com/bgetting/hominid"
12
12
  gem.authors = ["Brian Getting", "Michael Strüder"]
13
- gem.add_development_dependency "shoulda"
14
13
  end
15
14
  Jeweler::GemcutterTasks.new
16
15
  rescue LoadError
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.0.1
1
+ 2.0.2
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{hominid}
8
- s.version = "2.0.1"
8
+ s.version = "2.0.2"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Brian Getting", "Michael Str\303\274der"]
12
- s.date = %q{2009-11-11}
12
+ s.date = %q{2009-12-17}
13
13
  s.description = %q{Hominid is a Ruby gem that provides a wrapper for interacting with the Mailchimp email marketing service API.}
14
14
  s.email = %q{brian@terra-firma-design.com}
15
15
  s.extra_rdoc_files = [
@@ -23,14 +23,12 @@ Gem::Specification.new do |s|
23
23
  "Rakefile",
24
24
  "VERSION",
25
25
  "hominid.gemspec",
26
- "hominid.yml.tpl",
27
26
  "lib/hominid.rb",
28
27
  "lib/hominid/base.rb",
29
28
  "lib/hominid/campaign.rb",
30
29
  "lib/hominid/helper.rb",
31
30
  "lib/hominid/list.rb",
32
- "lib/hominid/webhook.rb",
33
- "tasks/rails/hominid.rake",
31
+ "lib/hominid/security.rb",
34
32
  "test/hominid_test.rb",
35
33
  "test/test_helper.rb"
36
34
  ]
@@ -49,12 +47,9 @@ Gem::Specification.new do |s|
49
47
  s.specification_version = 3
50
48
 
51
49
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
52
- s.add_development_dependency(%q<shoulda>, [">= 0"])
53
50
  else
54
- s.add_dependency(%q<shoulda>, [">= 0"])
55
51
  end
56
52
  else
57
- s.add_dependency(%q<shoulda>, [">= 0"])
58
53
  end
59
54
  end
60
55
 
@@ -11,26 +11,17 @@ module Hominid
11
11
  super("<#{error.faultCode}> #{error.message}")
12
12
  end
13
13
  end
14
-
15
- class ListError < APIError
16
- end
17
-
18
- class ListEmailError < ListError
19
- end
20
-
21
- class ListMergeError < ListError
22
- end
23
-
24
- class AlreadySubscribed < ListEmailError
14
+
15
+ class CampaignError < APIError
25
16
  end
26
-
27
- class AlreadyUnsubscribed < ListEmailError
17
+
18
+ class ListError < APIError
28
19
  end
29
-
30
- class NotExists < ListEmailError
20
+
21
+ class UserError < APIError
31
22
  end
32
-
33
- class NotSubscribed < ListEmailError
23
+
24
+ class ValidationError < APIError
34
25
  end
35
26
 
36
27
  class CommunicationError < StandardError
@@ -38,17 +29,11 @@ module Hominid
38
29
  super(message)
39
30
  end
40
31
  end
32
+
41
33
  end
42
34
 
43
- begin
44
- # include the provided rake task
45
- require 'rake'
46
- unless Rake::Task.task_defined? "hominid:config"
47
- load File.join(File.dirname(__FILE__), '..', 'tasks', 'rails', 'hominid.rake')
48
- end
49
- rescue LoadError
50
- # silently skip rake task inclusion unless the rake gem is installed
51
- end
52
-
35
+ require 'hominid/campaign'
36
+ require 'hominid/helper'
37
+ require 'hominid/list'
38
+ require 'hominid/security'
53
39
  require 'hominid/base'
54
-
@@ -1,76 +1,55 @@
1
1
  module Hominid
2
2
  class Base
3
-
3
+ include Hominid::Campaign
4
+ include Hominid::Helper
5
+ include Hominid::List
6
+ include Hominid::Security
7
+
4
8
  # MailChimp API Documentation: http://www.mailchimp.com/api/1.2/
5
9
  MAILCHIMP_API_VERSION = "1.2"
6
10
 
7
11
  def initialize(config = {})
8
- if defined?(Rails.root) && (!config || config.empty?)
9
- config = YAML.load(File.open("#{Rails.root}/config/hominid.yml"))[Rails.env].symbolize_keys
10
- end
11
- api_endpoint = config[:api_key].split('-').last
12
- config.merge(:username => config[:username].to_s, :password => config[:password].to_s)
13
- defaults = {:send_welcome => false,
14
- :double_opt_in => false,
15
- :update_existing => true,
16
- :replace_interests => true,
17
- :merge_tags => {},
18
- :secure => false}
12
+ raise StandardError.new('Please provide your Mailchimp API key.') unless config[:api_key]
13
+ dc = config[:api_key].split('-').last
14
+ defaults = {
15
+ :double_opt_in => false,
16
+ :merge_tags => {},
17
+ :replace_interests => true,
18
+ :secure => false,
19
+ :send_goodbye => false,
20
+ :send_notify => false,
21
+ :send_welcome => false,
22
+ :update_existing => true
23
+ }
19
24
  @config = defaults.merge(config).freeze
20
25
  if config[:secure]
21
- @chimpApi = XMLRPC::Client.new2("https://#{api_endpoint}.api.mailchimp.com/#{MAILCHIMP_API_VERSION}/")
26
+ @chimpApi = XMLRPC::Client.new2("https://#{dc}.api.mailchimp.com/#{MAILCHIMP_API_VERSION}/")
22
27
  else
23
- @chimpApi = XMLRPC::Client.new2("http://#{api_endpoint}.api.mailchimp.com/#{MAILCHIMP_API_VERSION}/")
28
+ @chimpApi = XMLRPC::Client.new2("http://#{dc}.api.mailchimp.com/#{MAILCHIMP_API_VERSION}/")
24
29
  end
25
30
  end
26
-
27
- # Security related methods
31
+
28
32
  # --------------------------------
29
-
30
- def add_api_key
31
- @chimpApi.call("apikeyAdd", *@config.values_at(:username, :password, :api_key))
32
- end
33
-
34
- def expire_api_key
35
- @chimpApi.call("apikeyExpire", *@config.values_at(:username, :password, :api_key))
36
- end
37
-
38
- def api_keys(include_expired = false)
39
- username, password = *@config.values_at(:username, :password)
40
- @chimpApi.call("apikeys", username, password, include_expired)
41
- end
42
-
43
33
  # Used internally by Hominid
44
34
  # --------------------------------
45
35
 
46
- # handle common cases for which the Mailchimp API would raise Exceptions
47
- def clean_merge_tags(merge_tags)
48
- return {} unless merge_tags.is_a? Hash
49
- merge_tags.each do |key, value|
50
- if merge_tags[key].is_a? String
51
- merge_tags[key] = value.gsub("\v", '')
52
- elsif merge_tags[key].nil?
53
- merge_tags[key] = ''
54
- end
55
- end
56
- end
57
-
58
36
  def apply_defaults_to(options)
59
37
  @config.merge(options)
60
38
  end
61
-
39
+
62
40
  def call(method, *args)
63
41
  @chimpApi.call(method, @config[:api_key], *args)
64
42
  rescue XMLRPC::FaultException => error
43
+ # Handle common cases for which the Mailchimp API would raise Exceptions
65
44
  case error.faultCode
66
- when 230
67
- raise AlreadySubscribed.new(error)
68
- when 231
69
- raise AlreadyUnsubscribed.new(error)
70
- when 232
71
- raise NotExists.new(error)
72
- when 233, 215
73
- raise NotSubscribed.new(error)
45
+ when 100..199
46
+ raise UserError.new(error)
47
+ when 200..299
48
+ raise ListError.new(error)
49
+ when 300..399
50
+ raise CampaignError.new(error)
51
+ when 500..599
52
+ raise ValidationError.new(error)
74
53
  else
75
54
  raise APIError.new(error)
76
55
  end
@@ -85,6 +64,33 @@ module Hominid
85
64
  rescue Exception => error
86
65
  raise CommunicationError.new(error.message)
87
66
  end
88
- end
89
- end
67
+
68
+ def clean_merge_tags(merge_tags)
69
+ return {} unless merge_tags.is_a? Hash
70
+ merge_tags.each do |key, value|
71
+ if merge_tags[key].is_a? String
72
+ merge_tags[key] = value.gsub("\v", '')
73
+ elsif merge_tags[key].nil?
74
+ merge_tags[key] = ''
75
+ end
76
+ end
77
+ end
78
+
79
+ def hash_to_object(object)
80
+ return case object
81
+ when Hash
82
+ object = object.clone
83
+ object.each do |key, value|
84
+ object[key.downcase] = hash_to_object(value)
85
+ end
86
+ OpenStruct.new(object)
87
+ when Array
88
+ object = object.clone
89
+ object.map! { |i| hash_to_object(i) }
90
+ else
91
+ object
92
+ end
93
+ end
90
94
 
95
+ end
96
+ end