chimpactions 0.0.0 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +14 -2
- data/MIT-LICENSE +20 -0
- data/README.textile +134 -0
- data/Rakefile +44 -0
- data/app/controllers/chimpactions_controller.rb +123 -0
- data/app/models/chimpaction.rb +20 -0
- data/app/views/chimpactions/_errors.html.erb +10 -0
- data/app/views/chimpactions/_form.html.erb +26 -0
- data/app/views/chimpactions/_list.html.erb +6 -0
- data/app/views/chimpactions/edit.html.erb +4 -0
- data/app/views/chimpactions/index.html.erb +22 -0
- data/app/views/chimpactions/new.html.erb +4 -0
- data/app/views/chimpactions/webhooks.html.erb +26 -0
- data/chimpactions.gemspec +9 -4
- data/config/deploy/templates/nginx.conf.tpl_ +0 -0
- data/config/deploy/templates/unicorn.conf.tpl_ +0 -0
- data/config/routes.rb +8 -0
- data/lib/chimpactions.rb +210 -2
- data/lib/chimpactions/action.rb +73 -0
- data/lib/chimpactions/engine.rb +21 -0
- data/lib/chimpactions/exception.rb +14 -0
- data/lib/chimpactions/list.rb +113 -0
- data/lib/chimpactions/notifier.rb +9 -0
- data/lib/chimpactions/setup.rb +42 -0
- data/lib/chimpactions/subscriber.rb +125 -0
- data/lib/chimpactions/utility.rb +13 -0
- data/lib/chimpactions/version.rb +1 -1
- data/lib/generators/chimpactions/customize/customize_generator.rb +19 -0
- data/lib/generators/chimpactions/customize/templates/views/_errors.html.erb +10 -0
- data/lib/generators/chimpactions/customize/templates/views/_form.html.erb +26 -0
- data/lib/generators/chimpactions/customize/templates/views/_list.html.erb +6 -0
- data/lib/generators/chimpactions/customize/templates/views/edit.html.erb +4 -0
- data/lib/generators/chimpactions/customize/templates/views/index.html.erb +22 -0
- data/lib/generators/chimpactions/customize/templates/views/new.html.erb +4 -0
- data/lib/generators/chimpactions/customize/templates/views/webhooks.html.erb +26 -0
- data/lib/generators/chimpactions/install/install_generator.rb +19 -0
- data/lib/generators/chimpactions/install/templates/README +10 -0
- data/lib/generators/chimpactions/install/templates/chimpactions.yml +39 -0
- data/lib/generators/chimpactions/install/templates/chimpactions_initializer.rb +1 -0
- data/lib/generators/chimpactions/migration/migration_generator.rb +26 -0
- data/lib/generators/chimpactions/migration/templates/create_chimpactions.rb +16 -0
- data/lib/railtie.rb +16 -0
- metadata +82 -38
- data/.gitignore +0 -4
@@ -0,0 +1,9 @@
|
|
1
|
+
module Chimpactions
|
2
|
+
# Notifier for telling the List objects that Chimpactions is using a new connection.
|
3
|
+
class ListNotifier
|
4
|
+
# Notify the List class that we havea new connection to MailChimp
|
5
|
+
def update(chimpactions)
|
6
|
+
chimpactions::List.new_socket
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Chimpactions
|
2
|
+
#Utility class for ensuring everythign is ready for Chimpactions to do its work
|
3
|
+
module Setup
|
4
|
+
mattr_accessor :message
|
5
|
+
mattr_reader :errors
|
6
|
+
@@errors = ActiveSupport::OrderedHash.new
|
7
|
+
|
8
|
+
# Make sure we have the right info to proceed.
|
9
|
+
def self.ensure_initialization
|
10
|
+
@@errors = ActiveSupport::OrderedHash.new
|
11
|
+
self.error(:api_key, "Is not set!") if Chimpactions.mailchimp_api_key == "your_mailchimp_api_key" || Chimpactions.mailchimp_api_key.nil?
|
12
|
+
self.error(:ses_key, "Is not set!") if Chimpactions.mailchimp_ses_key == "your_mailchimp_ses_key" || Chimpactions.mailchimp_ses_key.nil?
|
13
|
+
# self.verify_api_key
|
14
|
+
@@message = "Chimpactions::Setup.initialize"
|
15
|
+
end
|
16
|
+
|
17
|
+
# Were there errors in the setup ?
|
18
|
+
def self.ok?
|
19
|
+
errors.empty?
|
20
|
+
end
|
21
|
+
|
22
|
+
# Check the gibbon connection to MailChimp
|
23
|
+
# Verify that the API key is good.
|
24
|
+
def self.verify
|
25
|
+
begin
|
26
|
+
Chimpactions.socket.chimpChatter()
|
27
|
+
rescue Exception => e
|
28
|
+
self.error(:api_key,"BAD API KEY::" << e.message)
|
29
|
+
false
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
# Register an error in the setup.
|
35
|
+
def self.error(parameter,message)
|
36
|
+
errors[parameter] = message
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,125 @@
|
|
1
|
+
module Chimpactions
|
2
|
+
#The Chimpactions Subscriber is the mix-in module for a
|
3
|
+
# local model.
|
4
|
+
#Once initialized, the local model inherits all Subscriber methods.
|
5
|
+
#ex.
|
6
|
+
#<pre>
|
7
|
+
# see chimpaction.yml for initializtaion options
|
8
|
+
#</pre>
|
9
|
+
module Subscriber
|
10
|
+
|
11
|
+
attr_accessor :merge_vars
|
12
|
+
|
13
|
+
# override for mix-in goodeness
|
14
|
+
def self.included(mod)
|
15
|
+
mod.send(:include, ClassMethods)
|
16
|
+
end
|
17
|
+
|
18
|
+
# listSubscribe(string apikey, string id, string email_address, array merge_vars, string email_type, bool double_optin, bool update_existing, bool replace_interests, bool send_welcome)
|
19
|
+
#
|
20
|
+
# Subscribe the provided email to a list.
|
21
|
+
#
|
22
|
+
# listUnsubscribe(string apikey, string id, string email_address, boolean delete_member, boolean send_goodbye, boolean send_notify)
|
23
|
+
#
|
24
|
+
# Unsubscribe the given email address from the list
|
25
|
+
module ClassMethods
|
26
|
+
def chimpactions
|
27
|
+
Chimpactions.actions.each{|action| action.execute(self)}
|
28
|
+
end
|
29
|
+
|
30
|
+
# Add the Subscriber to the specified list.
|
31
|
+
# @param [String, Fixnum, Chimpactions::List] list
|
32
|
+
def add_to(list, opts={})
|
33
|
+
list = validate_list(list)
|
34
|
+
list.socket.listSubscribe({:id => list.id, :email_address => self.email,
|
35
|
+
:merge_vars => self.merge_vars, :send_welcome => Chimpactions.default_send_welcome,
|
36
|
+
:double_optin => Chimpactions.default_double_optin,
|
37
|
+
:update_existing => Chimpactions.default_update_existing}.merge opts) == "true"
|
38
|
+
end
|
39
|
+
|
40
|
+
# Remove Subscriber from all lists in the account and add to the specified List
|
41
|
+
# @param [String, Fixnum, Chimpactions::List] list
|
42
|
+
def move_to(list)
|
43
|
+
list = validate_list(list)
|
44
|
+
# add to the specified list
|
45
|
+
if add_to(list) == true
|
46
|
+
#remove from all the others
|
47
|
+
Chimpactions.available_lists.each do |l|
|
48
|
+
remove_from(l) if l != list
|
49
|
+
end
|
50
|
+
true
|
51
|
+
else
|
52
|
+
false
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# Remove the Subscriber from the specified list.
|
57
|
+
# @param [String, Fixnum, Chimpactions::List] list
|
58
|
+
def remove_from(list, opts={})
|
59
|
+
list = validate_list(list)
|
60
|
+
list.socket.listUnsubscribe({:id => list.id, :email_address => self.email}.merge opts) == "true"
|
61
|
+
end
|
62
|
+
|
63
|
+
# Send the specified MailChimp pre-defined "Response Email" to this Subscriber
|
64
|
+
# @param [String, Fixnum, Chimpactions::List] list
|
65
|
+
def send_response_email(list, title)
|
66
|
+
list = validate_list(list)
|
67
|
+
false # stub for test failure
|
68
|
+
end
|
69
|
+
|
70
|
+
# Check if this Subscriber is on the specified list.
|
71
|
+
# @param [String, Fixnum, Chimpactions::List] list
|
72
|
+
# @return [Boolean]
|
73
|
+
def on_list?(list, opts={})
|
74
|
+
list = validate_list(list)
|
75
|
+
answer = list.socket.listMemberInfo({:id => list.id, :email_address => self.email}.merge opts)
|
76
|
+
answer['success'] == 1 && answer['errors'] == 0
|
77
|
+
end
|
78
|
+
|
79
|
+
# Check if this Subscriber is 'subscribed' to the list.
|
80
|
+
# @param [String, Fixnum, Chimpactions::List] list
|
81
|
+
# @return [Boolean]
|
82
|
+
def subscribed?(list,opts={})
|
83
|
+
list = validate_list(list)
|
84
|
+
answer = list.socket.listMemberInfo({:id => list.id, :email_address => self.email}.merge opts)
|
85
|
+
answer['success'] == 1 && answer['data'][0]['status'] == 'subscribed'
|
86
|
+
end
|
87
|
+
|
88
|
+
# @param [Hash] hash The Chimpactions mergemap
|
89
|
+
def merge_vars(hash = Chimpactions.merge_map)
|
90
|
+
collect_merge_vars(hash)
|
91
|
+
end
|
92
|
+
|
93
|
+
private
|
94
|
+
|
95
|
+
# Sync this Subscriber's info to the MailChimp list.
|
96
|
+
# @return [boolean] *true* or *false*
|
97
|
+
def sync_to_chimp
|
98
|
+
Chimpactions.available_lists.each do |l|
|
99
|
+
add_to(l)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
|
104
|
+
# Calls the specified method/attribute on the mix-in target
|
105
|
+
# @param [Hash] {'MAILCHIMP_MERGE_VAR' => 'model_attribute_or_method'}
|
106
|
+
# @return [Hash]
|
107
|
+
def collect_merge_vars(merge_hash)
|
108
|
+
merge_vars = Hash.new
|
109
|
+
merge_hash.each_pair do |key,val|
|
110
|
+
if self.respond_to?(val)
|
111
|
+
method_object = self.method(val.to_sym)
|
112
|
+
merge_vars[key] = method_object.call
|
113
|
+
end
|
114
|
+
end
|
115
|
+
merge_vars
|
116
|
+
end
|
117
|
+
|
118
|
+
# Wrapper for Chimpactions module list method
|
119
|
+
# @see Chimpactions.list(list)
|
120
|
+
def validate_list(list)
|
121
|
+
Chimpactions.list(list)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end #Module
|
125
|
+
end #Module
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Chimpactions
|
2
|
+
# Utility mix-in module
|
3
|
+
# Defines method_missing for accessing raw MC data as
|
4
|
+
# Object attributes.
|
5
|
+
module Utility
|
6
|
+
# Convenience method for accessing MailChimp data arrays
|
7
|
+
# as class attributes.
|
8
|
+
# ex. => List.id instead of List['id']
|
9
|
+
def method_missing(m, *args)
|
10
|
+
@raw.keys.include?(m.to_s) ? @raw[m.to_s] : super
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/lib/chimpactions/version.rb
CHANGED
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
require 'rails/generators/migration'
|
3
|
+
module Chimpactions
|
4
|
+
module Generators
|
5
|
+
class CustomizeGenerator < Rails::Generators::Base
|
6
|
+
include Rails::Generators::Migration
|
7
|
+
source_root File.expand_path('../templates/views', __FILE__)
|
8
|
+
def copy_views
|
9
|
+
# Views template
|
10
|
+
copy_file "index.html.erb", "app/views/chimpactions/index.html.erb"
|
11
|
+
copy_file "edit.html.erb", "app/views/chimpactions/edit.html.erb"
|
12
|
+
copy_file "new.html.erb", "app/views/chimpactions/new.html.erb"
|
13
|
+
copy_file "_form.html.erb", "app/views/chimpactions/_form.html.erb"
|
14
|
+
copy_file "_errors.html.erb", "app/views/chimpactions/_errors.html.erb"
|
15
|
+
copy_file "webhooks.html.erb", "app/views/chimpactions/webhooks.html.erb"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
<% if target.errors.any? %>
|
2
|
+
<div id="errorExplanation">
|
3
|
+
<h2><%= pluralize(target.errors.count, "error") %> prohibited this record from being saved:</h2>
|
4
|
+
<ul>
|
5
|
+
<% target.errors.full_messages.each do |msg| %>
|
6
|
+
<li><%= msg %></li>
|
7
|
+
<% end %>
|
8
|
+
</ul>
|
9
|
+
</div>
|
10
|
+
<% end %>
|
@@ -0,0 +1,26 @@
|
|
1
|
+
<style>
|
2
|
+
.ca_action_form {padding-bottom:25px;width:350px;}
|
3
|
+
.ca_action_form fieldset {background-color:inherit;padding:0px;margin:0px;}
|
4
|
+
.ca_action_form fieldset legend {background-color:inherit;}
|
5
|
+
.ca_action_form * {float:none;font-family: verdana, arial, helvetica, sans-serif;
|
6
|
+
font-size: 12px!important;
|
7
|
+
line-height: 14px!important;}
|
8
|
+
.ca_action_form label {padding:0 4px;}
|
9
|
+
.ca_action_form div {display:inline;}
|
10
|
+
.ca_action_form .field_with_errors input {border:1px solid red;}
|
11
|
+
.ca_action_form ol {list-style:none;padding:14px;margin: 0px auto;max-width:315px;}
|
12
|
+
.ca_action_form ol li{padding:4px;}
|
13
|
+
.ca_action_form .bold {font-weight:bold;}
|
14
|
+
</style>
|
15
|
+
<%= form_for @chimpaction, :html => {:class => 'ca_action_form'} do |c| %>
|
16
|
+
<%= render "chimpactions/errors", :target => @chimpaction %>
|
17
|
+
<fieldset>
|
18
|
+
<ol>
|
19
|
+
<li><%= c.label :when, {:class => 'bold'} %> <%= Chimpactions.registered_class_name%>.<%= c.text_field :whenn, {:size => '15'} %> </li>
|
20
|
+
<li><%= select(:chimpaction, :is, %w(= < >)) %> <%= c.text_field :value %><%= c.label '(Value)' %></li>
|
21
|
+
<li><%= c.label "THEN", {:class => 'bold'}%></li>
|
22
|
+
<li><%= select(:chimpaction, :action, %w(add_to move_to remove_from).map {|l| [l.gsub('_',' ').titleize , l]}) -%></li>
|
23
|
+
<li><%= collection_select(:chimpaction, :list, Chimpactions.available_lists, :name, :name)%></li>
|
24
|
+
<li><%= submit_tag "submit"%></li>
|
25
|
+
</fieldset>
|
26
|
+
<% end %>
|
@@ -0,0 +1,22 @@
|
|
1
|
+
<section>
|
2
|
+
<% %w(notice warning error).each do |msg| %>
|
3
|
+
<% unless flash[msg.to_sym].blank? %>
|
4
|
+
<div class='message <%=msg-%>'><p><%=flash[msg.to_sym]-%></p></div>
|
5
|
+
<% end %>
|
6
|
+
<% end %>
|
7
|
+
<h1>Current Chimpactions : </h1>
|
8
|
+
<ul>
|
9
|
+
<% @actions.each do |action|%>
|
10
|
+
<li> When a <%= @registered %> <%= action.whenn %> <%= action.is %> <%= action.value %> => <%= @registered%>.<%= action.action %> (<%= action.list %>)
|
11
|
+
<%= link_to 'Edit', edit_chimpaction_path(action) %> ||
|
12
|
+
<%= link_to 'Destroy', chimpaction_path(action.id), :confirm => 'Are you sure?', :method => :delete %></li>
|
13
|
+
<%end%>
|
14
|
+
</ul>
|
15
|
+
</section>
|
16
|
+
<section>
|
17
|
+
<h1> <%= link_to "Add New Chimpaction", new_chimpaction_path %> </h1>
|
18
|
+
</section>
|
19
|
+
<section>
|
20
|
+
<h1>Your MailChimp lists: </h1>
|
21
|
+
<%= render :partial => 'list', :collection => @lists if @lists.count > 0%>
|
22
|
+
</section>
|
@@ -0,0 +1,26 @@
|
|
1
|
+
<style>
|
2
|
+
.ca_list {list-style:none;padding:0px;}
|
3
|
+
</style>
|
4
|
+
<div style="font-size:1.2em; color:green;"><%= flash[:notice] if flash[:notice] %></div>
|
5
|
+
<ul class="ca_list">
|
6
|
+
<% @lists.each do |list|%>
|
7
|
+
<li><%= list.name%> ( ID : <%= list.id %> )
|
8
|
+
<% if list.webhook? == false %>
|
9
|
+
<%=link_to "Add Webhook", {:action => 'add_webhook', :id => list.web_id }%>
|
10
|
+
<% else %>
|
11
|
+
<%=link_to "REMOVE Webhook", {:action => 'delete_webhook', :id => list.web_id }%>
|
12
|
+
<%end%>
|
13
|
+
</li>
|
14
|
+
<%end%>
|
15
|
+
</ul>
|
16
|
+
|
17
|
+
<div style="margin-top:25px;"> Remember ! : in order to do something here, your <%= Chimpactions.registered_class_name %> class must define :
|
18
|
+
<pre>
|
19
|
+
...
|
20
|
+
def receive_webhook(post_from_mailchimp)
|
21
|
+
// do something with the MailChimp POST data here
|
22
|
+
end
|
23
|
+
...
|
24
|
+
</pre>
|
25
|
+
|
26
|
+
</div>
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
require 'rails/generators/migration'
|
3
|
+
module Chimpactions
|
4
|
+
module Generators
|
5
|
+
class InstallGenerator < Rails::Generators::Base
|
6
|
+
include Rails::Generators::Migration
|
7
|
+
source_root File.expand_path('../templates', __FILE__)
|
8
|
+
|
9
|
+
desc "Creates a Chimpactions initializer and copy locale files to your application."
|
10
|
+
def copy_config_yml
|
11
|
+
copy_file "chimpactions.yml", "config/chimpactions.yml"
|
12
|
+
end
|
13
|
+
|
14
|
+
def show_readme
|
15
|
+
readme "README" if behavior == :invoke
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
===============================================================================
|
2
|
+
Chimpactions is almost ready...
|
3
|
+
|
4
|
+
- Edit config/chimpactions.yml accordingly
|
5
|
+
- To use ActiveRecord data store for Actions:
|
6
|
+
- rails generate chimpactions:migration
|
7
|
+
- you can then visit the admin interface at http:yourapp/chimpactions
|
8
|
+
- To customize the Admin section above:
|
9
|
+
- rails generate chimpactions:customize
|
10
|
+
===============================================================================
|
@@ -0,0 +1,39 @@
|
|
1
|
+
mailchimp_api_key: your_mailchimp_api_key
|
2
|
+
mailchimp_ses_key: your_mailchimp_ses_key
|
3
|
+
# Mappings of YOUR MailChimp Merge Variables
|
4
|
+
# => This list should include ANY merge variables throughout your MailChimp
|
5
|
+
# account from any and all lists.
|
6
|
+
# => Chimpactions will fail gracefully (i.e. not try to send) on any varibles
|
7
|
+
# either not set by your model, or not in the particular list.
|
8
|
+
# => If your model does not respond_to?('your_models_attribute_or_method')
|
9
|
+
# the merge variable will be skipped (not sent).
|
10
|
+
# @format :: MAILCHIMP_MERGE_VAR: 'model_attribute_or_method'
|
11
|
+
merge_map:
|
12
|
+
FNAME: first_name
|
13
|
+
LNAME: last_name
|
14
|
+
EMAIL: email
|
15
|
+
FAV_COL: favorite_color
|
16
|
+
# The local model to target for mix-in of the Chimpactions gem.
|
17
|
+
# This effectively makes the defined model as a Chimpactions::Subscriber
|
18
|
+
local_model: YourLocalModel
|
19
|
+
default_double_optin: false #default false Require the user to reply to the MailChimp system before adding to list.
|
20
|
+
default_send_welcome: true #default true Have MailChimp send the "Welcome" email for the list immediately.
|
21
|
+
default_email_type: html # 'nuff said... html ot text
|
22
|
+
# Storage method for Chimpactions persistence
|
23
|
+
# => :active_record OR :yml
|
24
|
+
# :active_record => ActiveRecord DB model (see migration)
|
25
|
+
# :yml => manually defined in this file with :
|
26
|
+
# actions:
|
27
|
+
# -
|
28
|
+
# action: :move_to
|
29
|
+
# list: "A MailChimp List Name"
|
30
|
+
# whenn: "your_method_or_attribute_1"
|
31
|
+
# is: '='
|
32
|
+
# value: 'the_value_1'
|
33
|
+
# -
|
34
|
+
# action: :remove_from
|
35
|
+
# list: "Another MailChimp List Name"
|
36
|
+
# whenn: "your_method_or_attribute_2"
|
37
|
+
# is: '='
|
38
|
+
# value: 'the_value_2'
|
39
|
+
action_store: :yml
|
@@ -0,0 +1 @@
|
|
1
|
+
ChimpactionsController.send(:before_filter, 'require_admin')
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
require 'rails/generators/migration'
|
3
|
+
module Chimpactions
|
4
|
+
module Generators
|
5
|
+
class MigrationGenerator < Rails::Generators::Base
|
6
|
+
include Rails::Generators::Migration
|
7
|
+
source_root File.expand_path('../templates', __FILE__)
|
8
|
+
|
9
|
+
desc "add the migrations"
|
10
|
+
def self.next_migration_number(path)
|
11
|
+
unless @prev_migration_nr
|
12
|
+
@prev_migration_nr = Time.now.utc.strftime("%Y%m%d%H%M%S").to_i
|
13
|
+
else
|
14
|
+
@prev_migration_nr += 1
|
15
|
+
end
|
16
|
+
@prev_migration_nr.to_s
|
17
|
+
end
|
18
|
+
|
19
|
+
desc "Add the Chimpactions migration to Rails db/migrate"
|
20
|
+
def copy_migrations
|
21
|
+
migration_template "create_chimpactions.rb", "db/migrate/create_chimpactions.rb"
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class CreateChimpactions < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :chimpactions, :force => true do |t|
|
4
|
+
t.text :action
|
5
|
+
t.text :list
|
6
|
+
t.string :whenn
|
7
|
+
t.string :is
|
8
|
+
t.string :value
|
9
|
+
t.timestamps
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.down
|
14
|
+
drop_table :chimpactions
|
15
|
+
end
|
16
|
+
end
|