effective_mailchimp 0.7.0 → 0.8.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_controller.rb +1 -3
- data/app/datatables/admin/effective_mailchimp_lists_datatable.rb +4 -0
- data/app/jobs/effective_mailchimp_subscribe_all_members_job.rb +8 -0
- data/app/jobs/effective_mailchimp_subscribe_all_users_job.rb +8 -0
- data/app/models/concerns/effective_mailchimp_user.rb +10 -9
- data/app/models/effective/mailchimp_api.rb +30 -6
- data/app/models/effective/mailchimp_category.rb +2 -1
- data/app/models/effective/mailchimp_interest.rb +2 -1
- data/app/models/effective/mailchimp_list.rb +39 -7
- data/app/views/admin/mailchimp/index.html.haml +7 -8
- data/config/effective_mailchimp.rb +6 -0
- data/config/routes.rb +5 -1
- data/db/migrate/101_create_effective_mailchimp.rb +2 -0
- data/lib/effective_mailchimp/version.rb +1 -1
- data/lib/effective_mailchimp.rb +22 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 56caa6a3804ed54f997cb2a732022cb077c37ec186f2a42476b2433b59f80bab
|
4
|
+
data.tar.gz: 51a5b095d91881d957c227c6f13155d78d3a9178aa3703982cf2fd4b8d92cd37
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 246b57c7659cbb154db572309d4a886132cef6cdf9d1bd09e4cafd37fd15dfc2d109375a2c179173bf710c478fb71306b1dc69a0c57587a6d66c4286edf6b446
|
7
|
+
data.tar.gz: 578e421f5e538bc705fcc0a4ab8290cd0adc4fae51388ddf941f934bbd4ea2c069eb13530d96c789ed4c8110d2e4ca5960a8274a1ae154e58cc30971a8722f3f
|
@@ -16,9 +16,7 @@ module Admin
|
|
16
16
|
EffectiveResources.authorize!(self, :admin, :mailchimp_sync)
|
17
17
|
|
18
18
|
api = EffectiveMailchimp.api
|
19
|
-
|
20
|
-
|
21
|
-
Effective::MailchimpList.sync!(api: api, merge_fields: merge_fields)
|
19
|
+
Effective::MailchimpList.sync!(api: api)
|
22
20
|
Effective::MailchimpCategory.sync!(api: api)
|
23
21
|
Effective::MailchimpInterest.sync!(api: api)
|
24
22
|
|
@@ -59,12 +59,13 @@ module EffectiveMailchimpUser
|
|
59
59
|
member.assign_attributes(subscribed: subscribed)
|
60
60
|
end
|
61
61
|
|
62
|
-
# This sets up the after_commit to run the mailchimp_update! job
|
63
|
-
assign_attributes(mailchimp_user_form_action: true)
|
64
|
-
|
65
62
|
# For use in a rake task. Run the update right now
|
66
|
-
|
63
|
+
if now
|
64
|
+
return mailchimp_update!(only: mailchimp_lists)
|
65
|
+
end
|
67
66
|
|
67
|
+
# This sets up the after_commit to run the mailchimp_update! job
|
68
|
+
assign_attributes(mailchimp_user_form_action: true)
|
68
69
|
save!
|
69
70
|
end
|
70
71
|
|
@@ -173,8 +174,7 @@ module EffectiveMailchimpUser
|
|
173
174
|
# Pulls the current status from Mailchimp API into the Mailchimp List Member objects
|
174
175
|
# Run before the mailchimp fields are displayed
|
175
176
|
# Only run in the background when a user or admin clicks sync now
|
176
|
-
def mailchimp_sync!
|
177
|
-
api = EffectiveMailchimp.api
|
177
|
+
def mailchimp_sync!(api: EffectiveMailchimp.api)
|
178
178
|
lists = Effective::MailchimpList.subscribable.sorted.to_a
|
179
179
|
|
180
180
|
assign_attributes(mailchimp_user_form_action: nil)
|
@@ -198,12 +198,13 @@ module EffectiveMailchimpUser
|
|
198
198
|
|
199
199
|
# Pushes the current Mailchimp List Member objects to Mailchimp when needed
|
200
200
|
# Called in the background after a form submission that changes the user email/last_name/first_name or mailchimp subscriptions
|
201
|
-
def mailchimp_update!
|
202
|
-
api = EffectiveMailchimp.api
|
203
|
-
|
201
|
+
def mailchimp_update!(api: EffectiveMailchimp.api, only: [], except: [])
|
204
202
|
assign_attributes(mailchimp_user_form_action: nil)
|
205
203
|
|
206
204
|
mailchimp_list_members.each do |member|
|
205
|
+
next if only.present? && Array(only).exclude?(member.mailchimp_list)
|
206
|
+
next if except.present? && Array(except).include?(member.mailchimp_list)
|
207
|
+
|
207
208
|
begin
|
208
209
|
list_member = if member.mailchimp_id.blank? && member.subscribed?
|
209
210
|
api.list_member_add(member)
|
@@ -25,6 +25,10 @@ module Effective
|
|
25
25
|
Rails.env.development?
|
26
26
|
end
|
27
27
|
|
28
|
+
def sandbox_mode?
|
29
|
+
EffectiveMailchimp.sandbox_mode?
|
30
|
+
end
|
31
|
+
|
28
32
|
def admin_url
|
29
33
|
"https://#{server}.admin.mailchimp.com"
|
30
34
|
end
|
@@ -56,27 +60,27 @@ module Effective
|
|
56
60
|
# Returns an Array of Lists, which are each Hash
|
57
61
|
# Like this [{ ...}, { ... }]
|
58
62
|
def lists
|
59
|
-
Rails.logger.info "[effective_mailchimp] Index Lists
|
63
|
+
Rails.logger.info "[effective_mailchimp] Index Lists" if debug?
|
60
64
|
|
61
65
|
response = client.lists.get_all_lists(count: 250)
|
62
66
|
Array(response['lists']) - [nil, '', {}]
|
63
67
|
end
|
64
68
|
|
65
69
|
def list(id)
|
66
|
-
Rails.logger.info "[effective_mailchimp]
|
70
|
+
Rails.logger.info "[effective_mailchimp] Get List" if debug?
|
67
71
|
|
68
72
|
client.lists.get_list(id.try(:mailchimp_id) || id)
|
69
73
|
end
|
70
74
|
|
71
75
|
def categories(list_id)
|
72
|
-
Rails.logger.info "[effective_mailchimp] Index Interest Categories
|
76
|
+
Rails.logger.info "[effective_mailchimp] Index Interest Categories" if debug?
|
73
77
|
|
74
78
|
response = client.lists.get_list_interest_categories(list_id.try(:mailchimp_id) || list_id)
|
75
79
|
Array(response['categories']) - [nil, '', {}]
|
76
80
|
end
|
77
81
|
|
78
82
|
def interests(list_id, category_id)
|
79
|
-
Rails.logger.info "[effective_mailchimp] Index Interest Category Interests
|
83
|
+
Rails.logger.info "[effective_mailchimp] Index Interest Category Interests" if debug?
|
80
84
|
|
81
85
|
response = client.lists.list_interest_category_interests(list_id, category_id)
|
82
86
|
Array(response['interests']) - [nil, '', {}]
|
@@ -85,6 +89,8 @@ module Effective
|
|
85
89
|
def list_member(id, email)
|
86
90
|
raise('expected an email') unless email.to_s.include?('@')
|
87
91
|
|
92
|
+
Rails.logger.info "[effective_mailchimp] Get List Member" if debug?
|
93
|
+
|
88
94
|
begin
|
89
95
|
client.lists.get_list_member(id.try(:mailchimp_id) || id, email)
|
90
96
|
rescue MailchimpMarketing::ApiError => e
|
@@ -93,18 +99,24 @@ module Effective
|
|
93
99
|
end
|
94
100
|
|
95
101
|
def list_merge_fields(id)
|
102
|
+
Rails.logger.info "[effective_mailchimp] Get List Merge Fields" if debug?
|
103
|
+
|
96
104
|
response = client.lists.get_list_merge_fields(id.try(:mailchimp_id) || id, count: 100)
|
97
|
-
Array(response['merge_fields']) - [nil, '', {}]
|
105
|
+
Array(response['merge_fields']) - [nil, '', ' ', {}]
|
98
106
|
end
|
99
107
|
|
100
108
|
def add_merge_field(id, name:, type: :text)
|
101
109
|
raise("invalid mailchimp merge key: #{name}. Must be 10 or fewer characters") if name.to_s.length > 10
|
102
110
|
|
111
|
+
return if sandbox_mode?
|
112
|
+
Rails.logger.info "[effective_mailchimp] Add List Merge Field #{name}" if debug?
|
113
|
+
|
103
114
|
payload = { name: name.to_s.titleize, tag: name.to_s, type: type }
|
104
115
|
|
105
116
|
begin
|
106
117
|
client.lists.add_list_merge_field(id.try(:mailchimp_id) || id, payload)
|
107
118
|
rescue MailchimpMarketing::ApiError => e
|
119
|
+
EffectiveLogger.error(e.message, details: name.to_s) if defined?(EffectiveLogger)
|
108
120
|
false
|
109
121
|
end
|
110
122
|
end
|
@@ -112,9 +124,18 @@ module Effective
|
|
112
124
|
def list_member_add(member)
|
113
125
|
raise('expected an Effective::MailchimpListMember') unless member.kind_of?(Effective::MailchimpListMember)
|
114
126
|
|
127
|
+
return if sandbox_mode?
|
128
|
+
Rails.logger.info "[effective_mailchimp] Add List Member" if debug?
|
129
|
+
|
130
|
+
# See if they exist somehow
|
115
131
|
existing = list_member(member.mailchimp_list, member.user.email)
|
116
|
-
return existing if existing.present?
|
117
132
|
|
133
|
+
if existing.present?
|
134
|
+
member.assign_attributes(mailchimp_id: existing['id'])
|
135
|
+
return list_member_update(member)
|
136
|
+
end
|
137
|
+
|
138
|
+
# Actually add
|
118
139
|
payload = list_member_payload(member)
|
119
140
|
client.lists.add_list_member(member.mailchimp_list.mailchimp_id, payload)
|
120
141
|
end
|
@@ -122,6 +143,9 @@ module Effective
|
|
122
143
|
def list_member_update(member)
|
123
144
|
raise('expected an Effective::MailchimpListMember') unless member.kind_of?(Effective::MailchimpListMember)
|
124
145
|
|
146
|
+
return if sandbox_mode?
|
147
|
+
Rails.logger.info "[effective_mailchimp] Update List Member" if debug?
|
148
|
+
|
125
149
|
payload = list_member_payload(member)
|
126
150
|
client.lists.update_list_member(member.mailchimp_list.mailchimp_id, member.email, payload)
|
127
151
|
end
|
@@ -25,7 +25,8 @@ module Effective
|
|
25
25
|
scope :sorted, -> { order(:name) }
|
26
26
|
scope :subscribable, -> { all }
|
27
27
|
|
28
|
-
#
|
28
|
+
# Reads all the InterestCategories from Mailchimp and creates local MailchimpCategory records
|
29
|
+
# This is part of the Sync changes from Mailchimp button
|
29
30
|
def self.sync!(api: EffectiveMailchimp.api)
|
30
31
|
# For every mailchimp_list, get all the categories
|
31
32
|
mailchimp_lists = Effective::MailchimpList.all
|
@@ -33,7 +33,8 @@ module Effective
|
|
33
33
|
scope :sorted, -> { order(:display_order) }
|
34
34
|
scope :subscribable, -> { where(can_subscribe: true) }
|
35
35
|
|
36
|
-
#
|
36
|
+
# Reads all the InterestCategoriesInterests from Mailchimp and creates local MailchimpInterest records
|
37
|
+
# This is part of the Sync changes from Mailchimp button
|
37
38
|
def self.sync!(api: EffectiveMailchimp.api)
|
38
39
|
# For every mailchimp_list, get all the interests
|
39
40
|
mailchimp_lists = Effective::MailchimpList.deep.all
|
@@ -22,8 +22,10 @@ module Effective
|
|
22
22
|
scope :sorted, -> { order(:name) }
|
23
23
|
scope :subscribable, -> { where(can_subscribe: true) }
|
24
24
|
|
25
|
-
#
|
26
|
-
|
25
|
+
# Reads all the Lists from Mailchimp and creates local MailchimpList records
|
26
|
+
# Also writes our merge fields to Mailchimp if they don't exist
|
27
|
+
# This is part of the Sync changes from Mailchimp button
|
28
|
+
def self.sync!(api: EffectiveMailchimp.api)
|
27
29
|
# All the Lists from Mailchimp
|
28
30
|
lists = api.lists()
|
29
31
|
|
@@ -40,6 +42,7 @@ module Effective
|
|
40
42
|
|
41
43
|
web_id: list['web_id'],
|
42
44
|
name: list['name'],
|
45
|
+
member_count: (list.dig('stats', 'member_count') || 0),
|
43
46
|
updated_at: Time.zone.now
|
44
47
|
)
|
45
48
|
|
@@ -54,21 +57,34 @@ module Effective
|
|
54
57
|
end
|
55
58
|
|
56
59
|
# Sync merge fields
|
57
|
-
if merge_fields.present?
|
60
|
+
if (merge_fields = EffectiveMailchimp.merge_fields).present?
|
58
61
|
merge_field_keys = merge_fields.keys.map(&:to_s)
|
59
62
|
|
60
63
|
mailchimp_lists.reject(&:destroyed?).each do |mailchimp_list|
|
61
64
|
existing = api.list_merge_fields(mailchimp_list).map { |hash| hash['tag'] }
|
62
|
-
(merge_field_keys - existing).each
|
63
|
-
puts "Adding merge field #{name} to #{mailchimp_list}"
|
64
|
-
api.add_merge_field(mailchimp_list, name: name)
|
65
|
-
end
|
65
|
+
(merge_field_keys - existing).each { |name| api.add_merge_field(mailchimp_list, name: name) }
|
66
66
|
end
|
67
67
|
end
|
68
68
|
|
69
69
|
true
|
70
70
|
end
|
71
71
|
|
72
|
+
def subscribe_all_users!(now: false)
|
73
|
+
if now
|
74
|
+
subscribe_all!(EffectiveMailchimp.User.all)
|
75
|
+
else
|
76
|
+
EffectiveMailchimpSubscribeAllUsersJob.perform_later(self)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def subscribe_all_members!(now: false)
|
81
|
+
if now
|
82
|
+
subscribe_all!(EffectiveMailchimp.User.all.members)
|
83
|
+
else
|
84
|
+
EffectiveMailchimpSubscribeAllMembersJob.perform_later(self)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
72
88
|
def to_s
|
73
89
|
name.presence || model_name.human
|
74
90
|
end
|
@@ -94,5 +110,21 @@ module Effective
|
|
94
110
|
EffectiveMailchimp.api.admin_url + "/lists/settings/merge-tags?id=#{web_id}"
|
95
111
|
end
|
96
112
|
|
113
|
+
private
|
114
|
+
|
115
|
+
def subscribe_all!(users)
|
116
|
+
users.find_each do |user|
|
117
|
+
begin
|
118
|
+
user.mailchimp_subscribe!(self, subscribed: true, now: true)
|
119
|
+
rescue => e
|
120
|
+
EffectiveLogger.error(e.message, associated: user) if defined?(EffectiveLogger)
|
121
|
+
ExceptionNotifier.notify_exception(e, data: { user_id: user.id, mailchimp_list_id: id }) if defined?(ExceptionNotifier)
|
122
|
+
raise(e) if Rails.env.test? || Rails.env.development?
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
true
|
127
|
+
end
|
128
|
+
|
97
129
|
end
|
98
130
|
end
|
@@ -20,14 +20,13 @@
|
|
20
20
|
= link_to('campaigns', EffectiveMailchimp.api.campaigns_url, target: '_blank')
|
21
21
|
at anytime.
|
22
22
|
|
23
|
-
%p.
|
24
|
-
%small
|
25
|
-
To change the names or display order of items below, please visit the Mailchimp website then sync changes.
|
26
|
-
%br
|
27
|
-
This operation also creates the audience merge fields and updates the subscriber counts for each group below.
|
23
|
+
%p To change the names or display order of items below, please visit the Mailchimp website then sync changes.
|
28
24
|
|
29
25
|
= render('admin/mailchimp/sync')
|
30
26
|
|
27
|
+
%p.text-muted
|
28
|
+
%small This operation also creates the audience merge fields and updates the member and subscriber counts below.
|
29
|
+
|
31
30
|
= collapse('More settings') do
|
32
31
|
%p
|
33
32
|
For more information see
|
@@ -44,7 +43,7 @@
|
|
44
43
|
%p The following merge fields are sent to Mailchimp when a user subscribes:
|
45
44
|
|
46
45
|
%ul
|
47
|
-
-
|
46
|
+
- EffectiveMailchimp.merge_fields.keys.sort.each do |key|
|
48
47
|
%li= key
|
49
48
|
|
50
49
|
.mb-4
|
@@ -60,7 +59,7 @@
|
|
60
59
|
Press the Edit button to change the Can Subscribe and Force Subscribe settings.
|
61
60
|
|
62
61
|
- datatable = Admin::EffectiveMailchimpListsDatatable.new
|
63
|
-
= render_datatable(datatable,
|
62
|
+
= render_datatable(datatable, inline: true, short: true, search: false, sort: false)
|
64
63
|
|
65
64
|
= card(Effective::MailchimpCategory) do
|
66
65
|
%p
|
@@ -76,5 +75,5 @@
|
|
76
75
|
- Effective::MailchimpCategory.all.each do |mailchimp_category|
|
77
76
|
= card(mailchimp_category.to_s) do
|
78
77
|
- datatable = Admin::EffectiveMailchimpInterestsDatatable.new(mailchimp_category: mailchimp_category)
|
79
|
-
= render_datatable(datatable,
|
78
|
+
= render_datatable(datatable, inline: true, short: true, search: false, sort: false)
|
80
79
|
|
@@ -5,4 +5,10 @@ EffectiveMailchimp.setup do |config|
|
|
5
5
|
|
6
6
|
# Mailchimp Settings
|
7
7
|
config.api_key = '' # From mailchimp's /account/api/ screen
|
8
|
+
|
9
|
+
# In Sandbox Mode you can only READ from Mailchimp not actually write to it
|
10
|
+
config.sandbox_mode = false
|
11
|
+
|
12
|
+
# Assign the User class name. For use in determining all merge_fields
|
13
|
+
# config.user_class_name = 'User'
|
8
14
|
end
|
data/config/routes.rb
CHANGED
@@ -13,7 +13,11 @@ EffectiveMailchimp::Engine.routes.draw do
|
|
13
13
|
end
|
14
14
|
|
15
15
|
namespace :admin do
|
16
|
-
resources :mailchimp_lists, only: [:index, :edit, :update]
|
16
|
+
resources :mailchimp_lists, only: [:index, :edit, :update] do
|
17
|
+
post :subscribe_all_users, on: :member
|
18
|
+
post :subscribe_all_members, on: :member
|
19
|
+
end
|
20
|
+
|
17
21
|
resources :mailchimp_interests, only: [:index, :edit, :update]
|
18
22
|
resources :mailchimp_categories, only: :index
|
19
23
|
resources :mailchimp_list_members, only: :index
|
data/lib/effective_mailchimp.rb
CHANGED
@@ -9,7 +9,7 @@ module EffectiveMailchimp
|
|
9
9
|
[
|
10
10
|
:mailchimp_lists_table_name, :mailchimp_list_members_table_name, :mailchimp_categories_table_name, :mailchimp_interests_table_name,
|
11
11
|
:layout,
|
12
|
-
:api_key
|
12
|
+
:api_key, :sandbox_mode, :user_class_name
|
13
13
|
]
|
14
14
|
end
|
15
15
|
|
@@ -19,6 +19,10 @@ module EffectiveMailchimp
|
|
19
19
|
Effective::MailchimpApi.new(api_key: api_key)
|
20
20
|
end
|
21
21
|
|
22
|
+
def self.sandbox_mode?
|
23
|
+
!!sandbox_mode
|
24
|
+
end
|
25
|
+
|
22
26
|
def self.api_present?
|
23
27
|
api_key.present?
|
24
28
|
end
|
@@ -27,6 +31,23 @@ module EffectiveMailchimp
|
|
27
31
|
api_key.blank?
|
28
32
|
end
|
29
33
|
|
34
|
+
def self.User
|
35
|
+
klass = user_class_name.constantize if user_class_name.present?
|
36
|
+
klass ||= Tenant.User if defined?(Tenant)
|
37
|
+
klass ||= '::User'.safe_constantize
|
38
|
+
|
39
|
+
raise('unable to determine User klass. Please set config.user_class_name') unless klass.kind_of?(Class)
|
40
|
+
raise('expecting an effective_mailchimp_user User class') unless klass.respond_to?(:effective_mailchimp_user)
|
41
|
+
|
42
|
+
klass
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.merge_fields
|
46
|
+
merge_fields = self.User().new.mailchimp_merge_fields
|
47
|
+
raise('expected a Hash of merge fields') unless merge_fields.kind_of?(Hash)
|
48
|
+
merge_fields
|
49
|
+
end
|
50
|
+
|
30
51
|
def self.permitted_params
|
31
52
|
[ :mailchimp_user_form_action, mailchimp_list_members_attributes: [:id, :mailchimp_list_id, :subscribed, interests: []] ]
|
32
53
|
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.8.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: 2024-07-
|
11
|
+
date: 2024-07-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -204,6 +204,8 @@ files:
|
|
204
204
|
- app/datatables/admin/effective_mailchimp_list_members_datatable.rb
|
205
205
|
- app/datatables/admin/effective_mailchimp_lists_datatable.rb
|
206
206
|
- app/helpers/effective_mailchimp_helper.rb
|
207
|
+
- app/jobs/effective_mailchimp_subscribe_all_members_job.rb
|
208
|
+
- app/jobs/effective_mailchimp_subscribe_all_users_job.rb
|
207
209
|
- app/jobs/effective_mailchimp_update_job.rb
|
208
210
|
- app/models/concerns/effective_mailchimp_user.rb
|
209
211
|
- app/models/effective/mailchimp_api.rb
|