Can hard sync a mailchimp list
This commit is contained in:
parent
fd5b1a68ef
commit
9d4925dc78
6 changed files with 115 additions and 0 deletions
5
app/models/email_list.rb
Normal file
5
app/models/email_list.rb
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
class EmailList < ActiveRecord::Base
|
||||||
|
attr_accessible :list_name, :mailchimp_list_id
|
||||||
|
belongs_to :nonprofit
|
||||||
|
belongs_to :tag_master
|
||||||
|
end
|
|
@ -8,6 +8,7 @@ class TagJoin < ActiveRecord::Base
|
||||||
validates :tag_master, presence: true
|
validates :tag_master, presence: true
|
||||||
|
|
||||||
belongs_to :tag_master
|
belongs_to :tag_master
|
||||||
|
belongs_to :supporter
|
||||||
|
|
||||||
def name; self.tag_master.name; end
|
def name; self.tag_master.name; end
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ class TagMaster < ActiveRecord::Base
|
||||||
|
|
||||||
belongs_to :nonprofit
|
belongs_to :nonprofit
|
||||||
has_many :tag_joins, dependent: :destroy
|
has_many :tag_joins, dependent: :destroy
|
||||||
|
has_one :email_list
|
||||||
|
|
||||||
scope :not_deleted, ->{where(deleted: [nil,false])}
|
scope :not_deleted, ->{where(deleted: [nil,false])}
|
||||||
|
|
||||||
|
|
|
@ -154,4 +154,60 @@ module Mailchimp
|
||||||
.execute.map{|h| h['mailchimp_list_id']}
|
.execute.map{|h| h['mailchimp_list_id']}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
# @param [Nonprofit] nonprofit
|
||||||
|
def self.hard_sync_lists(nonprofit)
|
||||||
|
return if !nonprofit
|
||||||
|
|
||||||
|
nonprofit.tag_masters.not_deleted.each do |i|
|
||||||
|
if (i.email_list)
|
||||||
|
hard_sync_list(i.email_list)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# @param [EmailList] email_list
|
||||||
|
def self.hard_sync_list(email_list)
|
||||||
|
ops = generate_batch_ops_for_hard_sync(email_list)
|
||||||
|
perform_batch_operations(email_list.nonprofit.id, ops)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.generate_batch_ops_for_hard_sync(email_list)
|
||||||
|
#get the subscribers from mailchimp
|
||||||
|
mailchimp_subscribers = get_list_mailchimp_subscribers(email_list)
|
||||||
|
#get our subscribers
|
||||||
|
our_supporters = email_list.tag_master.tag_joins.map{|i| i.supporter}
|
||||||
|
|
||||||
|
#split them as follows:
|
||||||
|
# on both lists, on our list, on the mailchimp list
|
||||||
|
in_both, in_mailchimp_only = mailchimp_subscribers.partition do |mc_sub|
|
||||||
|
our_supporters.any?{|s| s.email.downcase == mc_sub[:email_address].downcase}
|
||||||
|
end
|
||||||
|
|
||||||
|
_, in_our_side_only = our_supporters.partition do |s|
|
||||||
|
mailchimp_subscribers.any?{|mc_sub| s.email.downcase == mc_sub[:email_address].downcase}
|
||||||
|
end
|
||||||
|
|
||||||
|
# if on our list, add to mailchimp
|
||||||
|
output = in_our_side_only.map{|i|
|
||||||
|
{method: 'POST', path: "lists/#{email_list.mailchimp_list_id}/members", body: {email_address: i.email, status: 'subscribed'}.to_json}
|
||||||
|
}
|
||||||
|
|
||||||
|
# if on mailchimp list, delete from mailchimp
|
||||||
|
output = output.concat(in_mailchimp_only.map{|i| {method: 'DELETE', path: "lists/#{email_list.mailchimp_list_id}/members/#{i[:id]}"}})
|
||||||
|
|
||||||
|
return output
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.get_list_mailchimp_subscribers(email_list)
|
||||||
|
mailchimp_token = get_mailchimp_token(email_list.tag_master.nonprofit.id)
|
||||||
|
uri = base_uri(mailchimp_token)
|
||||||
|
result = get(uri + "/lists/#{email_list.mailchimp_list_id}/members", {
|
||||||
|
basic_auth: {username: "CommitChange", password: mailchimp_token},
|
||||||
|
headers: {'Content-Type' => 'application/json'}})
|
||||||
|
members = result['members'].map do |i|
|
||||||
|
{id: i['id'], email_address: i['email_address']}
|
||||||
|
end.to_a
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
5
spec/factories/email_lists.rb
Normal file
5
spec/factories/email_lists.rb
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
FactoryBot.define do
|
||||||
|
factory :email_list do
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
47
spec/lib/mailchimp_spec.rb
Normal file
47
spec/lib/mailchimp_spec.rb
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
# License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
describe Mailchimp do
|
||||||
|
describe '.hard_sync_list' do
|
||||||
|
let(:ret_val) { [{id: 'on_both', email_address: 'on_both@email.com'},
|
||||||
|
{id: 'on_mailchimp', email_address: 'on_mailchimp@email.com'}]}
|
||||||
|
|
||||||
|
let(:np) { force_create(:nonprofit)}
|
||||||
|
let(:tag_master) {force_create(:tag_master, nonprofit: np)}
|
||||||
|
let(:email_list) {force_create(:email_list, mailchimp_list_id: 'list_id', tag_master: tag_master, nonprofit:np, list_name: "temp")}
|
||||||
|
let(:supporter_on_both) { force_create(:supporter, nonprofit:np, email: 'on_BOTH@email.com')}
|
||||||
|
let(:supporter_on_local) { force_create(:supporter, nonprofit:np, email: 'on_local@email.com')}
|
||||||
|
let(:tag_join) {force_create(:tag_join, tag_master: tag_master, supporter: supporter_on_both)}
|
||||||
|
|
||||||
|
let(:tag_join2) {force_create(:tag_join, tag_master: tag_master, supporter: supporter_on_local)}
|
||||||
|
|
||||||
|
|
||||||
|
it 'excepts when excepting' do
|
||||||
|
expect(Mailchimp).to receive(:get_list_mailchimp_subscribers).with(email_list).and_raise
|
||||||
|
|
||||||
|
expect{ Mailchimp.generate_batch_ops_for_hard_sync(email_list)}.to raise_error
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'passes' do
|
||||||
|
tag_join
|
||||||
|
tag_join2
|
||||||
|
email_list
|
||||||
|
|
||||||
|
expect(Mailchimp).to receive(:get_list_mailchimp_subscribers).with(email_list).and_return(ret_val)
|
||||||
|
|
||||||
|
result = Mailchimp.generate_batch_ops_for_hard_sync(email_list)
|
||||||
|
|
||||||
|
expect(result).to contain_exactly(
|
||||||
|
{
|
||||||
|
method: 'POST',
|
||||||
|
path: 'lists/list_id/members',
|
||||||
|
body: {email_address: supporter_on_local.email, status: 'subscribed'}.to_json
|
||||||
|
},
|
||||||
|
{
|
||||||
|
method: 'DELETE',
|
||||||
|
path: 'lists/list_id/members/on_mailchimp'
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
Loading…
Reference in a new issue