Permalink
Browse files

Initial commit

  • Loading branch information...
0 parents commit 43359175edce9ad7d57e9c66520049d571c623cd @jcnnghm committed Oct 27, 2011
@@ -0,0 +1,5 @@
+.idea
+*.gem
+.bundle
+Gemfile.lock
+pkg/*
@@ -0,0 +1,4 @@
+source "http://rubygems.org"
+
+# Specify your gem's dependencies in devise_mailchimp.gemspec
+gemspec
@@ -0,0 +1,14 @@
+Copyright (c) 2011 Justin Cunningham
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
+rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
+persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,78 @@
+= Devise MailChimp
+
+Devise MailChimp adds a MailChimp option to {devise}[https://github.com/plataformatec/devise] that easily enables users
+to join your mailing list when they create an account.
+
+{Delayed Job}[https://github.com/collectiveidea/delayed_job] is used automatically if your project uses it, and the
+mapping between list names and list ids is cached automatically.
+
+== Getting started
+
+In your Gemfile, add devise_mailchimp after devise:
+
+ gem "devise"
+ gem "devise_mailchimp" # Last officially released gem
+
+In your User model, add :mailchimp to the devise call:
+
+ devise :database_authenticatable, ..., :mailchimp
+
+In your devise initializer (config/initializers/devise.rb), set your API key and mailing list name:
+
+ Devise.mailchimp_api_key = 'your_api_key'
+ Devise.mailing_list_name = 'List Name'
+
+If you are using the default Devise registration views, the Join Mailing List checkbox is added automatically, if not,
+either include the form partial in your new registration form:
+
+ <%= render :partial => "devise/shared/mailchimp/form", :locals => {:form => f} %>
+
+Or manually add a "Join Mailing List" checkbox to your new registration form:
+
+ <%=form.check_box :join_mailing_list%>
+
+== Configuration
+
+Create an initializer, and set your MailChimp API key. To generate a new API key, go to the account tab in your
+MailChimp account and select API Keys & Authorized Apps, then add a key.
+
+ Devise.mailchimp_api_key = 'your_api_key'
+
+Create a mailing list, and set the mailing list name in the initializer. To create a MailChimp list, from your account
+go to the Lists tab, then hit create list.
+
+ Devise.mailing_list_name = 'List Name'
+
+== Example Usage
+
+Users will join the default mailing list if join_mailing_list is set to true when the user is created. To manually add
+a user:
+
+ User.find(1).add_to_mailchimp_list('Site Administrators List')
+
+To manually remove a user:
+
+ User.find(1).remove_from_mailchimp_list('Site Administrators List')
+
+NOTE: You MUST have the users permission to add them to a mailing list.
+
+== Customization
+
+To have the user join more than one list, or to override the lists that the user will join, override
+mailchimp_lists_to_join in your model. Your method should return a single list, or an array of lists.
+
+ def mailchimp_lists_to_join
+ lists = ["Site Users List"]
+ lists << "Site Admins List" if admin?
+ return lists
+ end
+
+If all users will join the same list or lists, just set the mailing_list_name configuration option.
+
+== Contributions
+
+Please help this software improve by submitting pull requests, preferably with tests.
+
+== Copyright
+
+Copyright (c) 2011 {Justin Cunningham}[http://littlebitofcode.com]. See MIT_LICENSE for details.
@@ -0,0 +1 @@
+require "bundler/gem_tasks"
@@ -0,0 +1,20 @@
+<h2>Sign up</h2>
+
+<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
+ <%= devise_error_messages! %>
+
+ <div><%= f.label :email %><br />
+ <%= f.email_field :email %></div>
+
+ <div><%= f.label :password %><br />
+ <%= f.password_field :password %></div>
+
+ <div><%= f.label :password_confirmation %><br />
+ <%= f.password_field :password_confirmation %></div>
+
+ <%= render :partial => "devise/shared/mailchimp/form", :locals => {:form => f} %>
+
+ <div><%= f.submit "Sign up" %></div>
+<% end %>
+
+<%= render :partial => "devise/shared/links" %>
@@ -0,0 +1,2 @@
+ <div><%= form.label :join_mailing_list %><br />
+ <%=form.check_box :join_mailing_list%></div>
@@ -0,0 +1,32 @@
+# -*- encoding: utf-8 -*-
+$:.push File.expand_path("../lib", __FILE__)
+require "devise_mailchimp/version"
+
+Gem::Specification.new do |s|
+ s.name = "devise_mailchimp"
+ s.version = DeviseMailchimp::VERSION
+ s.authors = ["Justin Cunningham"]
+ s.email = ["justin@compucatedsolutions.com"]
+ s.homepage = "https://github.com/jcnnghm/devise_mailchimp"
+ s.summary = %q{Easy MailChimp integration for Devise}
+ s.description = %q{Devise MailChimp adds a MailChimp option to devise that easily enables users to join your mailing list when they create an account.}
+
+ s.rubyforge_project = "devise_mailchimp"
+
+ s.files = `git ls-files`.split("\n")
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
+ s.require_paths = ["lib"]
+
+ {
+ 'rails' => ['>= 3.0.0', '< 3.2'],
+ 'devise' => '~> 1.4.8',
+ 'hominid' => "~> 3.0.2"
+ }.each do |lib, version|
+ s.add_runtime_dependency(lib, *version)
+ end
+
+ # specify any dependencies here; for example:
+ # s.add_development_dependency "rspec"
+ # s.add_runtime_dependency "rest-client"
+end
@@ -0,0 +1,42 @@
+require 'devise'
+
+require "devise_mailchimp/version"
+
+module DeviseMailchimp
+ class Engine < Rails::Engine
+ end
+ # Your code goes here...
+end
+
+module Devise
+ # Public: Default mailing list for user to join. This can be an array of strings, or just one string.
+ # By default, this is "Site List". If this will be configurable for each user, override
+ # mailchimp_lists_to_join returning the list name or an array of list names for the user to
+ # join.
+ # Set mailing_list_name in the Devise configuration file (config/initializers/devise.rb)
+ #
+ # Devise.mailing_list_name = "Your Mailing List Name"
+ mattr_accessor :mailing_list_name
+ @@mailing_list_name = "Site List"
+
+ # Public: Determines if the checkbox for the user to opt-in to the mailing list should
+ # be checked by default, or not. Defaults to true.
+ # Set mailing_list_opt_in_by_default in the Devise configuration file (config/initializers/devise.rb)
+ #
+ # Devise.mailing_list_opt_in_by_default = false
+ mattr_accessor :mailing_list_opt_in_by_default
+ @@mailing_list_opt_in_by_default = true
+
+ # Public: The API key for accessing the mailchimp service. To generate a new API key, go to the
+ # account tab in your MailChimp account and select API Keys & Authorized Apps, then add
+ # a key. This defaults to 'your_api_key'
+ # Set mailchimp_api_key in the Devise configuration file (config/initializers/devise.rb)
+ #
+ # Devise.mailchimp_api_key = "your_api_key"
+ mattr_accessor :mailchimp_api_key
+ @@mailchimp_api_key = 'your_api_key'
+end
+
+Devise.add_module :mailchimp, :model => 'devise_mailchimp/model'
+
+require 'devise_mailchimp/mailchimp_list_api_mapper'
@@ -0,0 +1,78 @@
+require 'hominid'
+
+module Devise
+ module Models
+ module Mailchimp
+ class MailchimpListApiMapper
+ LIST_CACHE_KEY = "devise_mailchimp/lists"
+
+ # craete a new ApiMapper with the provided API key
+ def initialize(api_key)
+ @api_key = api_key
+ end
+
+ # looks the name up in the cache. if it doesn't find it, looks it up using the api and saves it to the cache
+ def name_to_id(list_name)
+ load_cached_lists
+ if @lists.has_key?(list_name)
+ return @lists[list_name]
+ else
+ list_id = hominid.find_list_id_by_name(list_name)
+ if list_id.nil?
+ raise ListLookupError
+ else
+ @lists[list_name] = list_id
+ save_cached_lists
+ return @lists[list_name]
+ end
+ end
+ end
+
+ # subscribes the user to the named mailing list(s). list_names can be the name of one list, or an array of
+ # several.
+ #
+ # NOTE: Do not use this method unless the user has opted in.
+ def subscribe_to_lists(list_names, email)
+ list_names = [list_names] unless list_names.is_a?(Array)
+ list_names.each do |list_name|
+ list_id = name_to_id(list_name)
+ hominid.list_subscribe(list_id, email, {}, 'html', false, true, true, false)
+ end
+ end
+
+ # unsubscribe the user from the named mailing list(s). list_names can be the name of one list, or an array of
+ # several.
+ def unsubscribe_from_lists(list_names, email)
+ list_names = [list_names] unless list_names.is_a?(Array)
+ list_names.each do |list_name|
+ list_id = name_to_id(list_name)
+ hominid.list_unsubscribe(list_id, email, false, false, false)
+ # don't delete, send goodbye, or send notification
+ end
+ end
+
+
+ class ListLookupError < RuntimeError; end
+
+ private
+
+ # load the list from the cache
+ def load_cached_lists
+ @lists ||= Rails.cache.fetch(LIST_CACHE_KEY) do
+ {}
+ end.dup
+ end
+
+ # save the modified list back to the cache
+ def save_cached_lists
+ Rails.cache.write(LIST_CACHE_KEY, @lists)
+ end
+
+ # the hominid api helper
+ def hominid
+ @hominid ||= Hominid::API.new(@api_key)
+ end
+ end
+ end
+ end
+end
@@ -0,0 +1,86 @@
+module Devise
+ module Models
+ # Mailchimp is responsible for joining users to mailchimp lists when the create accounts with devise
+ # When a user is created, and join_mailing_list is set to true, they will automatically be added to one or more
+ # mailing lists returned by mailchimp_lists_to_join.
+ #
+ # Configuration
+ #
+ # mailing_list_name: Default mailing list for user to join. This can be an array of strings, or just one string.
+ # By default, this is "Site List". If this will be configurable for each user, override
+ # mailchimp_lists_to_join returning the list name or an array of list names for the user to
+ # join.
+ #
+ # mailing_list_opt_in_by_default: Determines if the checkbox for the user to opt-in to the mailing list should
+ # be checked by default, or not. Defaults to true.
+ #
+ # mailchimp_api_key: The API key for accessing the mailchimp service. To generate a new API key, go to the
+ # account tab in your MailChimp account and select API Keys & Authorized Apps, then add
+ # a key. This defaults to 'your_api_key'
+ #
+ # Examples:
+ #
+ # User.find(1).add_to_mailchimp_list('Site Administrators List')
+ # User.find(1).remove_from_mailchimp_list('Site Administrators List')
+ #
+ # u = User.new
+ # u.join_mailing_list = true
+ # u.save
+ module Mailchimp
+ extend ActiveSupport::Concern
+
+ included do
+ after_create :commit_mailing_list_join
+ end
+
+ # Set this to true to have the user automatically join the mailchimp_lists_to_join
+ def join_mailing_list=(join)
+ join.downcase! if join.is_a?(String)
+ true_values = ['yes','true',true,'1',1]
+ join = true_values.include?(join)
+ @join_mailing_list = join
+ end
+
+ #
+ def join_mailing_list
+ @join_mailing_list.nil? ? self.class.mailing_list_opt_in_by_default : @join_mailing_list
+ end
+
+ # The mailing list or lists the user will join
+ # Should return either a single string or an array of strings. By default, returns the mailing_list_name
+ # configuration option. If you want to customize the lists based on other information, override this method in
+ # your model.
+ def mailchimp_lists_to_join
+ self.class.mailing_list_name
+ end
+
+ # Add the user to the mailchimp list with the specified name
+ def add_to_mailchimp_list(list_name)
+ mapper = mailchimp_list_mapper.respond_to?(:delay) ? mailchimp_list_mapper.delay : mailchimp_list_mapper
+ mapper.subscribe_to_lists(list_name, self.email)
+ end
+
+ # remove the user from the mailchimp list with the specified name
+ def remove_from_mailchimp_list(list_name)
+ mapper = mailchimp_list_mapper.respond_to?(:delay) ? mailchimp_list_mapper.delay : mailchimp_list_mapper
+ mapper.unsubscribe_from_lists(list_name, self.email)
+ end
+
+ # Commit the user to the mailing list if they have selected to join
+ def commit_mailing_list_join
+ add_to_mailchimp_list(mailchimp_lists_to_join) if @join_mailing_list
+ end
+
+ # mapper that helps convert list names to mailchimp ids
+ def mailchimp_list_mapper
+ @@mailchimp_list_mapper ||= MailchimpListApiMapper.new(self.class.mailchimp_api_key)
+ end
+
+ module ClassMethods
+ Devise::Models.config(self, :mailchimp_api_key)
+ Devise::Models.config(self, :mailing_list_name)
+ Devise::Models.config(self, :mailing_list_opt_in_by_default)
+ end
+ end
+ end
+end
@@ -0,0 +1,3 @@
+module DeviseMailchimp
+ VERSION = "0.0.1"
+end

0 comments on commit 4335917

Please sign in to comment.