Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
effective_mailchimp (0.13.0)
effective_mailchimp (0.13.2)
MailchimpMarketing
effective_bootstrap
effective_datatables (>= 4.0.0)
Expand Down Expand Up @@ -391,7 +391,6 @@ DEPENDENCIES
effective_test_bot
haml-rails
pry-byebug
psych
sqlite3
wicked

Expand Down
29 changes: 21 additions & 8 deletions app/models/effective/mailchimp_api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# https://mailchimp.com/developer/marketing/api/

require 'MailchimpMarketing'
require 'digest'

module Effective
class MailchimpApi
Expand Down Expand Up @@ -75,14 +76,14 @@ def list(id)
def categories(list_id)
Rails.logger.info "[effective_mailchimp] Index Interest Categories" if debug?

response = client.lists.get_list_interest_categories(list_id.try(:mailchimp_id) || list_id)
response = client.lists.get_list_interest_categories(list_id.try(:mailchimp_id) || list_id, count: 1000)
Array(response['categories']) - [nil, '', {}]
end

def interests(list_id, category_id)
Rails.logger.info "[effective_mailchimp] Index Interest Category Interests" if debug?

response = client.lists.list_interest_category_interests(list_id, category_id)
response = client.lists.list_interest_category_interests(list_id, category_id, count: 1000)
Array(response['interests']) - [nil, '', {}]
end

Expand All @@ -92,7 +93,7 @@ def list_member(id, email)
Rails.logger.info "[effective_mailchimp] Get List Member" if debug?

begin
client.lists.get_list_member(id.try(:mailchimp_id) || id, email)
client.lists.get_list_member(id.try(:mailchimp_id) || id, subscriber_hash(email))
rescue MailchimpMarketing::ApiError => e
{}
end
Expand Down Expand Up @@ -127,9 +128,9 @@ def list_member_add(member)
Rails.logger.info "[effective_mailchimp] Add List Member" if debug?
return if sandbox_mode?

# Actually add or update
payload = list_member_payload(member)
client.lists.set_list_member(member.mailchimp_list.mailchimp_id, member.email, payload)
# Actually add or update. set_list_member applies status_if_new when the contact is new
payload = list_member_payload(member).merge(status_if_new: list_member_status(member))
client.lists.set_list_member(member.mailchimp_list.mailchimp_id, subscriber_hash(member.user.email), payload)
end

def list_member_update(member)
Expand All @@ -139,7 +140,8 @@ def list_member_update(member)
return if sandbox_mode?

payload = list_member_payload(member)
client.lists.update_list_member(member.mailchimp_list.mailchimp_id, member.email, payload)
hash = member.mailchimp_id.presence || subscriber_hash(member.email)
client.lists.update_list_member(member.mailchimp_list.mailchimp_id, hash, payload)
end

def list_member_payload(member)
Expand All @@ -150,11 +152,22 @@ def list_member_payload(member)

payload = {
email_address: member.user.email,
status: (member.subscribed ? 'subscribed' : 'unsubscribed'),
status: list_member_status(member),
merge_fields: merge_fields.transform_values { |value| value || '' },
interests: member.interests_hash.presence
}.compact
end

# Mailchimp identifies a list member by the MD5 hash of their lowercase email address
def subscriber_hash(email)
raise('expected an email') unless email.to_s.include?('@')

Digest::MD5.hexdigest(email.to_s.downcase.strip)
end

def list_member_status(member)
member.subscribed ? 'subscribed' : 'unsubscribed'
end

end
end
24 changes: 24 additions & 0 deletions test/models/mailchimp_api_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
require 'test_helper'

class MailchimpApiTest < ActiveSupport::TestCase
def api
@api ||= Effective::MailchimpApi.new(api_key: 'test-us1')
end

test 'subscriber_hash is the md5 of the lowercase email' do
expected = Digest::MD5.hexdigest('brenda.barrera@quadreal.com')

assert_equal expected, api.subscriber_hash('brenda.barrera@quadreal.com')
end

test 'subscriber_hash lowercases and strips before hashing' do
expected = Digest::MD5.hexdigest('brenda.barrera@quadreal.com')

assert_equal expected, api.subscriber_hash(' Brenda.Barrera@QuadReal.com ')
end

test 'subscriber_hash raises without an email' do
assert_raises(RuntimeError) { api.subscriber_hash('not-an-email') }
end

end