chimpactions 0.0.0 → 0.0.4
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/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
|