Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
justincinmd committed Oct 27, 2011
0 parents commit 4335917
Show file tree
Hide file tree
Showing 12 changed files with 365 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .gitignore
@@ -0,0 +1,5 @@
.idea
*.gem
.bundle
Gemfile.lock
pkg/*
4 changes: 4 additions & 0 deletions Gemfile
@@ -0,0 +1,4 @@
source "http://rubygems.org"

# Specify your gem's dependencies in devise_mailchimp.gemspec
gemspec
14 changes: 14 additions & 0 deletions MIT_LICENSE
@@ -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.
78 changes: 78 additions & 0 deletions README
@@ -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.
1 change: 1 addition & 0 deletions Rakefile
@@ -0,0 +1 @@
require "bundler/gem_tasks"
20 changes: 20 additions & 0 deletions app/views/devise/registrations/new.html.erb
@@ -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" %>
2 changes: 2 additions & 0 deletions app/views/devise/shared/mailchimp/_form.html.erb
@@ -0,0 +1,2 @@
<div><%= form.label :join_mailing_list %><br />
<%=form.check_box :join_mailing_list%></div>
32 changes: 32 additions & 0 deletions devise_mailchimp.gemspec
@@ -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
42 changes: 42 additions & 0 deletions lib/devise_mailchimp.rb
@@ -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'
78 changes: 78 additions & 0 deletions lib/devise_mailchimp/mailchimp_list_api_mapper.rb
@@ -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
86 changes: 86 additions & 0 deletions lib/devise_mailchimp/model.rb
@@ -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
3 changes: 3 additions & 0 deletions lib/devise_mailchimp/version.rb
@@ -0,0 +1,3 @@
module DeviseMailchimp
VERSION = "0.0.1"
end

0 comments on commit 4335917

Please sign in to comment.