Class: MailchimpNewsletter

Inherits:
Newsletter
  • Object
show all
Defined in:
app/models/mailchimp_newsletter.rb

Overview

Integrates MailChimp into our system. Using the ‘gibbon’ gem to interface with MailChimp API V2


Constant Summary collapse

MAILCHIMP_ERRORS =
{  200 => 'List_DoesNotExist',
   214 => 'List_AlreadySubscribed',
   232 => 'Email_NotExists'
}.freeze

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Newsletter

find_newsletter

Class Method Details

.apiObject

Grab an API object to work with




161
162
163
164
165
166
167
# File 'app/models/mailchimp_newsletter.rb', line 161

def self.api
  if !.current.preferred_nms_api_key.blank?
    Gibbon::API.new(.current.preferred_nms_api_key)
  else
    nil
  end
end

.signup_information(token, options = {}) ⇒ Object




15
16
17
18
19
20
21
22
23
24
25
# File 'app/models/mailchimp_newsletter.rb', line 15

def self.(token, options = {})
  information = { newsletter: self.find_newsletter(token, options) }
  if information[:newsletter]
    information[:grouping] = information[:newsletter].groupings[0]
    if options[:current_user]
      subscriber = MailchimpNewsletterSubscriber.subscriber_info(information[:newsletter], options[:current_user].email)
      information[:subscriber] = (subscriber && subscriber.subscribed? ? subscriber : nil)
    end
  end
  return information
end

Instance Method Details

#email_subscribed?(email) ⇒ Boolean

is the email already subscribed to this list


Returns:

  • (Boolean)


171
172
173
174
# File 'app/models/mailchimp_newsletter.rb', line 171

def email_subscribed?(email)
  subscriber = MailchimpNewsletterSubscriber.subscriber_info(self, email)
  return subscriber.present? && subscriber.subscribed?
end

#folder_list(type = 'campaign') ⇒ Object




148
149
150
151
152
# File 'app/models/mailchimp_newsletter.rb', line 148

def folder_list(type = 'campaign')
  api         = MailchimpNewsletter.api
  folder_list = api.folders.list(type: type)
  folder_list.sort! {|x, y| x['name'] <=> y['name']}
end

#groupingsObject

Retrieve list of groupings from Mailchimp




43
44
45
46
47
48
49
50
51
# File 'app/models/mailchimp_newsletter.rb', line 43

def groupings
  begin
    api       = MailchimpNewsletter.api
    groupings = api.lists.interest_groupings(id: self.mc_id)
  rescue Gibbon::MailChimpError => exception
    #--- groupings are not enabled for this list
    return []
  end
end

#map_error_to_msg(code) ⇒ Object




155
156
157
# File 'app/models/mailchimp_newsletter.rb', line 155

def map_error_to_msg(code)
  return MAILCHIMP_ERRORS[code] ? "nms.#{MAILCHIMP_ERRORS[code]}" : 'nms.mc_unknown_error'
end

#sent_campaign_list(options = {start: 0, limit: 100}) ⇒ Object

get a list of sent campaigns. Can specify :folder_id to get only those in a specfic folder




126
127
128
129
130
131
132
133
134
135
# File 'app/models/mailchimp_newsletter.rb', line 126

def sent_campaign_list(options = {start: 0, limit: 100})
  api                 = MailchimpNewsletter.api
  list_params         = {sort_field: 'send_time', sort_dir: 'DESC', 
                        filters: {list_id: self.mc_id}}
  list_params[:start] = options[:start] ? options[:start] : 0
  list_params[:limit] = options[:limit] ? options[:limit] : 100
  list_params[:filters][:folder_id] = options[:folder_id] if options[:folder_id]
    
  campaigns   = api.campaigns.list(list_params)
end

#sent_campaign_list_simple(options = {start: 0, limit: 100}) ⇒ Object

Get simplified list of sent campaigns. Useful for showing archived campaigns on the front end




140
141
142
143
144
145
# File 'app/models/mailchimp_newsletter.rb', line 140

def sent_campaign_list_simple(options = {start: 0, limit: 100})
  list      = sent_campaign_list(options)
  campaigns = list['data'].map {|item| {subject:      item['subject'], 
                                        sent_on:      item['send_time'].to_datetime,
                                        archive_url:  item['archive_url']} }
end

#subscribe(user_or_email, options = {FNAME: '', LNAME: ''}) ⇒ Object

subscribe user or email to the newsletter Setting the Accept-Language will cause MC to send the confirmation in the users language if the list auto-translate is turned on




57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'app/models/mailchimp_newsletter.rb', line 57

def subscribe(user_or_email, options = {FNAME: '', LNAME: ''})
  return { success: false, code: 232 } if user_or_email.blank?
  api         = MailchimpNewsletter.api
  headers     = {'Accept-Language' => I18n.locale.to_s}

  #--- update data if user logged in. Don't for an unprotected subscribe. but honor value if passed in
  options.reverse_merge!  update_existing: user_or_email.is_a?(User)

  #--- remove any invalid merge vars or other options
  merge_vars = options.except('new-email', :email, :optin_ip, :optin_time, :mc_location, :mc_notes,
                              :update_existing, :mc_language, :headers)

  #--- groupings needs to be an Array, but the form usually sends it as a Hash
  merge_vars['GROUPINGS'] = [merge_vars['GROUPINGS']] if merge_vars['GROUPINGS'] && !merge_vars['GROUPINGS'].is_a?(Array)

  if user_or_email.is_a?(User)
    email                 = {email: user_or_email.email}
    merge_vars[:FNAME]    = user_or_email.first_name
    merge_vars[:LNAME]    = user_or_email.last_name
    merge_vars[:COUNTRY]  = user_or_email.country.english_name if user_or_email.country
  else
    email               = {email: user_or_email}
  end
  merge_vars[:SPAMAPI]      = 1
  merge_vars[:MC_LANGUAGE]  = I18n.locale  # set the language to the current locale they are using
  api.lists.subscribe(id: self.mc_id, email: email, merge_vars: merge_vars, 
                      double_optin: true, update_existing: options[:update_existing], replace_interests: true,
                      headers: headers)
  return { success: true, code: 0 }
rescue Gibbon::MailChimpError => exception
  Rails.logger.info "=== Error Subscribing #{email} : #{exception.to_s}"
  return { success: false, code: exception.code }
end

#unsubscribe(email) ⇒ Object

unsubscribe email from the newsletter




93
94
95
96
97
98
99
100
101
102
# File 'app/models/mailchimp_newsletter.rb', line 93

def unsubscribe(email)
  return false if email.blank?

  api = MailchimpNewsletter.api
  api.lists.unsubscribe(id: self.mc_id, email: {email: email}, delete_member: false, send_goodbye: true, send_notify: true)
  return true
rescue Gibbon::MailChimpError => exception
  Rails.logger.info "=== Error Unsubscribing #{email} : #{exception.to_s}"
  return false
end

#update_list_statsObject




105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'app/models/mailchimp_newsletter.rb', line 105

def update_list_stats
  api         = MailchimpNewsletter.api
  list_info   = api.lists.list(filters: {list_id: self.mc_id, exact: true})

  #--- update the newsletter
  if list_info['errors'].empty?
    self.update_attributes(
      name:               list_info['data'][0]['name'],
      subscribed_count:   list_info['data'][0]['stats']['member_count'],
      unsubscribed_count: list_info['data'][0]['stats']['unsubscribe_count'],
      cleaned_count:      list_info['data'][0]['stats']['cleaned_count'],
      created_at:         list_info['data'][0]['date_created'])
  else
    #--- looks like the list was deleted at MailChimp, mark as deleted
    self.update_attribute(:deleted, true)
  end
end

#validate_list_idObject

Make sure list id is specified, and it’s valid with MailChimp




29
30
31
32
33
34
35
36
37
38
39
# File 'app/models/mailchimp_newsletter.rb', line 29

def validate_list_id
  unless self.mc_id.blank?
    api         = MailchimpNewsletter.api
    list_info   = api.lists.list(filters: {list_id: self.mc_id, exact: true})
    if !list_info['errors'].empty?
      errors[:mc_id] << (list_info['errors'][0]['error'])
    end
  else  
    errors[:mc_id] << ("list id must be provided")
  end
end