effective_mailchimp 0.2.5 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/controllers/admin/mailchimp_lists_controller.rb +10 -3
- data/app/controllers/effective/mailchimp_controller.rb +18 -0
- data/app/helpers/effective_mailchimp_helper.rb +0 -13
- data/app/jobs/effective_mailchimp_update_job.rb +1 -1
- data/app/models/concerns/effective_mailchimp_user.rb +75 -21
- data/app/models/effective/mailchimp_api.rb +15 -0
- data/app/models/effective/mailchimp_list_member.rb +6 -0
- data/app/views/admin/mailchimp_lists/index.html.haml +14 -10
- data/app/views/admin/mailchimp_user/_form.html.haml +2 -13
- data/app/views/admin/mailchimp_user/_sync.html.haml +15 -0
- data/app/views/effective/mailchimp_user/_fields.html.haml +5 -2
- data/app/views/effective/mailchimp_user/_sync.html.haml +15 -0
- data/config/routes.rb +5 -1
- data/lib/effective_mailchimp/version.rb +1 -1
- data/lib/effective_mailchimp.rb +1 -1
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6a5caed2328b202f012d4c813afb0c5038aa304b6b7efdcf30097bcc7ff7be2e
|
4
|
+
data.tar.gz: ed2fb79473591925eaf5ac5f2556464afb01269370e173215988afa33630dd12
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 272d0eda1823ee5df64c6f32612707cf5a80cabcd27b8cfd1ed346b2dc6e95142482e81fbc4f8c2bbd8afbce92be580898685b4c6833c83728bd30a408f8f9d4
|
7
|
+
data.tar.gz: 33c4543526fe5b465f4a2252482fd5d9774f62a06f2b82cc825274599f0e3f53f0a5f48891e66c4cb983451669f23e4e201c7979f4207e30e0051c7f49696f69
|
@@ -3,11 +3,18 @@ module Admin
|
|
3
3
|
before_action(:authenticate_user!) if defined?(Devise)
|
4
4
|
before_action { EffectiveResources.authorize!(self, :admin, :effective_mailchimp) }
|
5
5
|
|
6
|
-
# Calls Sync
|
7
|
-
before_action(only: :index) { Effective::MailchimpList.sync! }
|
8
|
-
|
9
6
|
include Effective::CrudController
|
10
7
|
|
8
|
+
def mailchimp_sync
|
9
|
+
EffectiveResources.authorize!(self, :mailchimp_sync, Effective::MailchimpList)
|
10
|
+
|
11
|
+
Effective::MailchimpList.sync!
|
12
|
+
|
13
|
+
flash[:success] = "Successfully synced mailchimp lists"
|
14
|
+
|
15
|
+
redirect_back(fallback_location: effective_mailchimp.admin_mailchimp_lists_path)
|
16
|
+
end
|
17
|
+
|
11
18
|
private
|
12
19
|
|
13
20
|
def permitted_params
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Effective
|
2
|
+
class MailchimpController < ApplicationController
|
3
|
+
before_action(:authenticate_user!) if defined?(Devise)
|
4
|
+
|
5
|
+
def mailchimp_sync_user
|
6
|
+
resource = current_user
|
7
|
+
|
8
|
+
EffectiveResources.authorize!(self, :mailchimp_sync_user, current_user)
|
9
|
+
|
10
|
+
resource.mailchimp_sync!
|
11
|
+
|
12
|
+
flash[:success] = "Successfully synced mailchimp"
|
13
|
+
|
14
|
+
redirect_back(fallback_location: '/settings')
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
@@ -1,15 +1,2 @@
|
|
1
1
|
module EffectiveMailchimpHelper
|
2
|
-
|
3
|
-
def mailchimp_user_fields(form)
|
4
|
-
raise('expected a form') unless form.respond_to?(:object)
|
5
|
-
|
6
|
-
resource = form.object
|
7
|
-
raise('expected an effective_mailchimp_user resource') unless resource.class.respond_to?(:effective_mailchimp_user?)
|
8
|
-
|
9
|
-
resource.reload
|
10
|
-
resource.mailchimp_sync!(force: false)
|
11
|
-
|
12
|
-
render('effective/mailchimp_user/fields', form: form, f: form, resource: resource, mailchimp_user: resource)
|
13
|
-
end
|
14
|
-
|
15
2
|
end
|
@@ -14,6 +14,10 @@ module EffectiveMailchimpUser
|
|
14
14
|
|
15
15
|
module ClassMethods
|
16
16
|
def effective_mailchimp_user?; true; end
|
17
|
+
|
18
|
+
def require_mailchimp_update_fields
|
19
|
+
['email', 'last_name', 'first_name']
|
20
|
+
end
|
17
21
|
end
|
18
22
|
|
19
23
|
included do
|
@@ -26,11 +30,54 @@ module EffectiveMailchimpUser
|
|
26
30
|
accepts_nested_attributes_for :mailchimp_lists, allow_destroy: true
|
27
31
|
|
28
32
|
# The user updated the form
|
29
|
-
after_commit(if: -> {
|
33
|
+
after_commit(if: -> { mailchimp_member_update_required? }) do
|
30
34
|
EffectiveMailchimpUpdateJob.perform_later(self)
|
31
35
|
end
|
32
36
|
end
|
33
37
|
|
38
|
+
def mailchimp_subscribed?(mailchimp_list)
|
39
|
+
raise('expected a MailchimpList') unless mailchimp_lists.all? { |list| list.kind_of?(Effective::MailchimpList) }
|
40
|
+
|
41
|
+
member = mailchimp_list_member(mailchimp_list: mailchimp_list)
|
42
|
+
return false if member.blank?
|
43
|
+
|
44
|
+
member.subscribed? && member.synced?
|
45
|
+
end
|
46
|
+
|
47
|
+
# Api method to just subscribe this user to this list right now
|
48
|
+
# Pass one list or an Array of lists
|
49
|
+
def mailchimp_subscribe!(mailchimp_list)
|
50
|
+
mailchimp_lists = Array(mailchimp_list)
|
51
|
+
raise('expected a MailchimpList') unless mailchimp_lists.all? { |list| list.kind_of?(Effective::MailchimpList) }
|
52
|
+
|
53
|
+
mailchimp_lists.each do |mailchimp_list|
|
54
|
+
member = build_mailchimp_list_member(mailchimp_list: mailchimp_list)
|
55
|
+
member.assign_attributes(subscribed: true)
|
56
|
+
end
|
57
|
+
|
58
|
+
# This sets up the after_commit to run the mailchimp_update! job
|
59
|
+
assign_attributes(mailchimp_user_form_action: true)
|
60
|
+
|
61
|
+
save!
|
62
|
+
end
|
63
|
+
|
64
|
+
# Api method to just unsubscribe this user to this list right now
|
65
|
+
# Pass one list or an Array of lists
|
66
|
+
def mailchimp_unsubscribe!(mailchimp_list)
|
67
|
+
mailchimp_lists = Array(mailchimp_list)
|
68
|
+
raise('expected a MailchimpList') unless mailchimp_lists.all? { |list| list.kind_of?(Effective::MailchimpList) }
|
69
|
+
|
70
|
+
mailchimp_lists.each do |mailchimp_list|
|
71
|
+
member = build_mailchimp_list_member(mailchimp_list: mailchimp_list)
|
72
|
+
member.assign_attributes(subscribed: false)
|
73
|
+
end
|
74
|
+
|
75
|
+
# This sets up the after_commit to run the mailchimp_update! job
|
76
|
+
assign_attributes(mailchimp_user_form_action: true)
|
77
|
+
|
78
|
+
save!
|
79
|
+
end
|
80
|
+
|
34
81
|
# Intended for app to extend
|
35
82
|
def mailchimp_merge_fields
|
36
83
|
default_mailchimp_merge_fields()
|
@@ -88,26 +135,29 @@ module EffectiveMailchimpUser
|
|
88
135
|
mailchimp_list_member(mailchimp_list: mailchimp_list) || mailchimp_list_members.build(mailchimp_list: mailchimp_list)
|
89
136
|
end
|
90
137
|
|
91
|
-
def mailchimp_list_members_changed?
|
92
|
-
mailchimp_list_members.any? { |mlm| mlm.changes.present? || mlm.marked_for_destruction? }
|
93
|
-
end
|
94
|
-
|
95
138
|
def mailchimp_last_synced_at
|
96
|
-
mailchimp_list_members.map(&:last_synced_at).min
|
139
|
+
mailchimp_list_members.map(&:last_synced_at).compact.min
|
97
140
|
end
|
98
141
|
|
99
|
-
|
100
|
-
|
101
|
-
|
142
|
+
# Used by the form to set it up for all lists
|
143
|
+
def build_mailchimp_list_members
|
144
|
+
mailchimp_lists = Effective::MailchimpList.subscribable.sorted.to_a
|
145
|
+
|
146
|
+
mailchimp_lists.each do |mailchimp_list|
|
147
|
+
build_mailchimp_list_member(mailchimp_list: mailchimp_list)
|
148
|
+
end
|
149
|
+
|
150
|
+
mailchimp_list_members
|
102
151
|
end
|
103
152
|
|
104
153
|
# Pulls the current status from Mailchimp API into the Mailchimp List Member objects
|
105
154
|
# Run before the mailchimp fields are displayed
|
106
|
-
|
155
|
+
# Only run in the background when a user or admin clicks sync now
|
156
|
+
def mailchimp_sync!
|
107
157
|
api = EffectiveMailchimp.api
|
108
158
|
lists = Effective::MailchimpList.subscribable.sorted.to_a
|
109
159
|
|
110
|
-
|
160
|
+
assign_attributes(mailchimp_user_form_action: nil)
|
111
161
|
|
112
162
|
Timeout::timeout(lists.length * 2) do
|
113
163
|
lists.each do |mailchimp_list|
|
@@ -123,12 +173,12 @@ module EffectiveMailchimpUser
|
|
123
173
|
member.mark_for_destruction unless list.present?
|
124
174
|
end
|
125
175
|
|
126
|
-
save!
|
127
|
-
true
|
176
|
+
save!
|
128
177
|
end
|
129
178
|
|
130
179
|
# Pushes the current Mailchimp List Member objects to Mailchimp when needed
|
131
|
-
|
180
|
+
# Called in the background after a form submission that changes the user email/last_name/first_name or mailchimp subscriptions
|
181
|
+
def mailchimp_update!
|
132
182
|
api = EffectiveMailchimp.api
|
133
183
|
|
134
184
|
assign_attributes(mailchimp_user_form_action: nil)
|
@@ -137,24 +187,28 @@ module EffectiveMailchimpUser
|
|
137
187
|
if member.mailchimp_id.blank? && member.subscribed?
|
138
188
|
list_member = api.list_member_add(member)
|
139
189
|
member.assign_mailchimp_attributes(list_member)
|
140
|
-
elsif member.mailchimp_id.present?
|
190
|
+
elsif member.mailchimp_id.present?
|
141
191
|
list_member = api.list_member_update(member)
|
142
192
|
member.assign_mailchimp_attributes(list_member)
|
143
193
|
end
|
144
194
|
end
|
145
195
|
|
146
|
-
save!
|
147
|
-
true
|
196
|
+
save!
|
148
197
|
end
|
149
198
|
|
150
|
-
|
151
|
-
|
199
|
+
private
|
200
|
+
|
201
|
+
def mailchimp_member_update_required?
|
202
|
+
return false unless mailchimp_user_form_action
|
152
203
|
|
204
|
+
# Update if my email first name or last name change
|
205
|
+
require_update = self.class.require_mailchimp_update_fields()
|
153
206
|
return true if (changes.keys & require_update).present?
|
154
207
|
return true if (previous_changes.keys & require_update).present?
|
155
208
|
|
156
|
-
|
157
|
-
|
209
|
+
# Update if any of my mailchimp list members changed
|
210
|
+
# which happens when I submit a form and change the Mailchimp values
|
211
|
+
return true if mailchimp_list_members.any? { |m| m.changes.present? || m.previous_changes.present? || m.marked_for_destruction? }
|
158
212
|
|
159
213
|
false
|
160
214
|
end
|
@@ -21,10 +21,18 @@ module Effective
|
|
21
21
|
@client.set_config(api_key: @api_key, server: @server)
|
22
22
|
end
|
23
23
|
|
24
|
+
def debug?
|
25
|
+
Rails.env.development?
|
26
|
+
end
|
27
|
+
|
24
28
|
def admin_url
|
25
29
|
"https://#{server}.admin.mailchimp.com"
|
26
30
|
end
|
27
31
|
|
32
|
+
def public_url
|
33
|
+
"https://mailchimp.com"
|
34
|
+
end
|
35
|
+
|
28
36
|
def ping
|
29
37
|
client.ping.get()
|
30
38
|
end
|
@@ -32,11 +40,15 @@ module Effective
|
|
32
40
|
# Returns an Array of Lists, which are each Hash
|
33
41
|
# Like this [{ ...}, { ... }]
|
34
42
|
def lists
|
43
|
+
Rails.logger.info "[effective_mailchimp] Index Lists..." if debug?
|
44
|
+
|
35
45
|
response = client.lists.get_all_lists(count: 250)
|
36
46
|
Array(response['lists']) - [nil, '', {}]
|
37
47
|
end
|
38
48
|
|
39
49
|
def list(id)
|
50
|
+
Rails.logger.info "[effective_mailchimp] Show List..." if debug?
|
51
|
+
|
40
52
|
client.lists.get_list(id.try(:mailchimp_id) || id)
|
41
53
|
end
|
42
54
|
|
@@ -70,6 +82,9 @@ module Effective
|
|
70
82
|
def list_member_add(member)
|
71
83
|
raise('expected an Effective::MailchimpListMember') unless member.kind_of?(Effective::MailchimpListMember)
|
72
84
|
|
85
|
+
existing = list_member(member.mailchimp_list, member.user.email)
|
86
|
+
return existing if existing.present?
|
87
|
+
|
73
88
|
merge_fields = member.user.mailchimp_merge_fields
|
74
89
|
raise('expected user mailchimp_merge_fields to be a Hash') unless merge_fields.kind_of?(Hash)
|
75
90
|
|
@@ -21,6 +21,8 @@ module Effective
|
|
21
21
|
timestamps
|
22
22
|
end
|
23
23
|
|
24
|
+
validates :mailchimp_list_id, uniqueness: { scope: [:user_type, :user_id] }
|
25
|
+
|
24
26
|
scope :deep, -> { includes(:mailchimp_list, :user) }
|
25
27
|
scope :sorted, -> { order(:id) }
|
26
28
|
|
@@ -43,5 +45,9 @@ module Effective
|
|
43
45
|
)
|
44
46
|
end
|
45
47
|
|
48
|
+
def synced?
|
49
|
+
last_synced_at.present?
|
50
|
+
end
|
51
|
+
|
46
52
|
end
|
47
53
|
end
|
@@ -1,16 +1,20 @@
|
|
1
1
|
%h1.effective-admin-heading= @page_title
|
2
2
|
|
3
|
-
.
|
4
|
-
.card-body
|
5
|
-
= collapse('Show merge field settings') do
|
6
|
-
%p The following Merge fields are sent to Mailchimp when a user subscribes:
|
3
|
+
- resource = (@_effective_resource || Effective::Resource.new(controller_path))
|
7
4
|
|
8
|
-
|
9
|
-
|
10
|
-
%li= key
|
5
|
+
.resource-buttons
|
6
|
+
= render_resource_buttons(resource.klass, (action ||= :index) => false)
|
11
7
|
|
12
|
-
|
8
|
+
= card do
|
9
|
+
= collapse('Show merge field settings') do
|
10
|
+
%p The following Merge fields are sent to Mailchimp when a user subscribes:
|
13
11
|
|
14
|
-
|
12
|
+
%ul
|
13
|
+
- current_user.mailchimp_merge_fields.keys.each do |key|
|
14
|
+
%li= key
|
15
15
|
|
16
|
-
|
16
|
+
%p To have these fields displayed in Mailchimp, please configure each campaign with any of these merge fields.
|
17
|
+
|
18
|
+
.mb-4
|
19
|
+
|
20
|
+
= render_datatable @datatable
|
@@ -12,18 +12,7 @@
|
|
12
12
|
= effective_form_with model: [:admin, user] do |f|
|
13
13
|
= f.hidden_field :id
|
14
14
|
|
15
|
-
=
|
16
|
-
|
17
|
-
%p.text-muted
|
18
|
-
%small
|
19
|
-
last synced with
|
20
|
-
= link_to 'Mailchimp', EffectiveMailchimp.api.admin_url
|
21
|
-
- if user.mailchimp_last_synced_at.present?
|
22
|
-
= time_ago_in_words(user.mailchimp_last_synced_at)
|
23
|
-
ago.
|
24
|
-
- else
|
25
|
-
never.
|
26
|
-
|
27
|
-
= link_to 'sync now', effective_mailchimp.mailchimp_sync_user_admin_mailchimp_path(f.object), 'data-method': :post
|
15
|
+
= render('effective/mailchimp_user/fields', f: f)
|
16
|
+
= render('admin/mailchimp_user/sync', f: f)
|
28
17
|
|
29
18
|
= f.submit
|
@@ -0,0 +1,15 @@
|
|
1
|
+
- user = f.object
|
2
|
+
|
3
|
+
- if user.persisted?
|
4
|
+
%p.text-muted
|
5
|
+
%small
|
6
|
+
last synced with
|
7
|
+
= link_to 'Mailchimp', EffectiveMailchimp.api.admin_url, target: '_blank'
|
8
|
+
- if user.mailchimp_last_synced_at.present?
|
9
|
+
= time_ago_in_words(user.mailchimp_last_synced_at)
|
10
|
+
ago.
|
11
|
+
- else
|
12
|
+
never.
|
13
|
+
|
14
|
+
- if EffectiveResources.authorized?(self, :mailchimp_sync_user, user)
|
15
|
+
= link_to 'sync now', effective_mailchimp.mailchimp_sync_user_admin_mailchimp_path(user), 'data-method': :post
|
@@ -1,12 +1,15 @@
|
|
1
1
|
= f.hidden_field :mailchimp_user_form_action, value: true
|
2
2
|
|
3
|
-
= f.fields_for :mailchimp_list_members do |fmlm|
|
3
|
+
= f.fields_for :mailchimp_list_members, f.object.build_mailchimp_list_members do |fmlm|
|
4
4
|
- mailchimp_list = fmlm.object.mailchimp_list
|
5
5
|
- next if mailchimp_list.blank?
|
6
6
|
|
7
|
+
= fmlm.hidden_field :id
|
8
|
+
= fmlm.hidden_field :mailchimp_list_id
|
9
|
+
|
7
10
|
- if mailchimp_list.force_subscribe?
|
8
11
|
%p
|
9
|
-
= fmlm.check_box :subscribed, label: fmlm.object.to_s, disabled: true, hint: 'required'
|
12
|
+
= fmlm.check_box :subscribed, label: fmlm.object.to_s, disabled: true, hint: 'required', checked: true
|
10
13
|
= fmlm.hidden_field :subscribed, value: true
|
11
14
|
|
12
15
|
- elsif mailchimp_list.can_subscribe?
|
@@ -0,0 +1,15 @@
|
|
1
|
+
- user = f.object
|
2
|
+
|
3
|
+
- if user.persisted?
|
4
|
+
%p.text-muted
|
5
|
+
%small
|
6
|
+
last synced with
|
7
|
+
= link_to 'Mailchimp', EffectiveMailchimp.api.public_url, target: '_blank'
|
8
|
+
- if user.mailchimp_last_synced_at.present?
|
9
|
+
= time_ago_in_words(user.mailchimp_last_synced_at)
|
10
|
+
ago.
|
11
|
+
- else
|
12
|
+
never.
|
13
|
+
|
14
|
+
- if EffectiveResources.authorized?(self, :mailchimp_sync_user, user)
|
15
|
+
= link_to 'sync now', effective_mailchimp.mailchimp_sync_user_mailchimp_path(user), 'data-method': :post
|
data/config/routes.rb
CHANGED
@@ -7,6 +7,9 @@ end
|
|
7
7
|
EffectiveMailchimp::Engine.routes.draw do
|
8
8
|
# Public routes
|
9
9
|
scope module: 'effective' do
|
10
|
+
resources :mailchimp, only: [] do
|
11
|
+
post :mailchimp_sync_user, on: :member
|
12
|
+
end
|
10
13
|
end
|
11
14
|
|
12
15
|
namespace :admin do
|
@@ -16,12 +19,13 @@ EffectiveMailchimp::Engine.routes.draw do
|
|
16
19
|
|
17
20
|
post :force_subscribe, on: :member
|
18
21
|
post :unforce_subscribe, on: :member
|
22
|
+
|
23
|
+
get :mailchimp_sync, on: :collection
|
19
24
|
end
|
20
25
|
|
21
26
|
resources :mailchimp, only: [] do
|
22
27
|
post :mailchimp_sync_user, on: :member
|
23
28
|
end
|
24
|
-
|
25
29
|
end
|
26
30
|
|
27
31
|
end
|
data/lib/effective_mailchimp.rb
CHANGED
@@ -24,7 +24,7 @@ module EffectiveMailchimp
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def self.permitted_params
|
27
|
-
[ :mailchimp_user_form_action, mailchimp_list_members_attributes: [:id, :subscribed] ]
|
27
|
+
[ :mailchimp_user_form_action, mailchimp_list_members_attributes: [:id, :mailchimp_list_id, :subscribed] ]
|
28
28
|
end
|
29
29
|
|
30
30
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: effective_mailchimp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Code and Effect
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-08-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -195,6 +195,7 @@ files:
|
|
195
195
|
- app/assets/stylesheets/effective_mailchimp/base.scss
|
196
196
|
- app/controllers/admin/mailchimp_controller.rb
|
197
197
|
- app/controllers/admin/mailchimp_lists_controller.rb
|
198
|
+
- app/controllers/effective/mailchimp_controller.rb
|
198
199
|
- app/datatables/admin/effective_mailchimp_lists_datatable.rb
|
199
200
|
- app/helpers/effective_mailchimp_helper.rb
|
200
201
|
- app/jobs/effective_mailchimp_update_job.rb
|
@@ -205,7 +206,9 @@ files:
|
|
205
206
|
- app/views/admin/mailchimp_lists/_form.html.haml
|
206
207
|
- app/views/admin/mailchimp_lists/index.html.haml
|
207
208
|
- app/views/admin/mailchimp_user/_form.html.haml
|
209
|
+
- app/views/admin/mailchimp_user/_sync.html.haml
|
208
210
|
- app/views/effective/mailchimp_user/_fields.html.haml
|
211
|
+
- app/views/effective/mailchimp_user/_sync.html.haml
|
209
212
|
- config/effective_mailchimp.rb
|
210
213
|
- config/routes.rb
|
211
214
|
- db/migrate/01_create_effective_mailchimp.rb.erb
|
@@ -235,7 +238,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
235
238
|
- !ruby/object:Gem::Version
|
236
239
|
version: '0'
|
237
240
|
requirements: []
|
238
|
-
rubygems_version: 3.
|
241
|
+
rubygems_version: 3.4.10
|
239
242
|
signing_key:
|
240
243
|
specification_version: 4
|
241
244
|
summary: Subscribe and unsubscribe to mailchimp lists.
|