Class: EmailNotification

Inherits:
Notification show all
Defined in:
lib/app/models/email_notification.rb

Overview

EmailNotification is a concrete class of Notification, sending emails to both members and users, or in the case of eCommerce, customers.

This object allows you to create an EmailNotification object, set it’s property and tell it send_notification. It’ll handle everything from there including

  1. Running in the background thread

  2. Error recovery

  3. Retry on failure

The Email object also uses the templating engine to allow the specification of a template and a set of local variables for dynamic content.

Usage:

email = EmailNotification.new email.to = ‘[email protected]’ email.sender = ‘[email protected]’ email.subject = ‘Today is the day!’ email.message = ‘Day is today!’ email.send_notification

You are done! Go about your business of creating awesome software!

Constant Summary

Constants inherited from Notification

Notification::ALL_STATES, Notification::DELIVERY_EMAIL, Notification::DELIVERY_SLACK, Notification::DELIVERY_SMS, Notification::STATE_INVALID, Notification::STATE_NEW, Notification::STATE_PROCESSED, Notification::STATE_PROCESSING, Notification::STATE_RESUBMITTED, Notification::STATE_RETRYING, Notification::STATE_SUBMITTED, Notification::STATE_VIEWED

Instance Method Summary collapse

Methods inherited from Notification

#account_message_template, #default_message_template, #deletable?, #deliver_message, #delivery_channel, #finish_processing, #message_from_haml_file, #message_from_haml_text, #message_from_liquid_text, #message_from_template, #render_liquid_text, #retry_delivery, #send_notification, #sendable?, #start_processing, #stringify_all, #successful?, #viewed

Methods included from StandardModel

#audit_action, #auto_strip_attributes, #capture_user_info, #clear_cache, #created_by_display_name, #delete_and_log, #destroy_and_log, included, #last_modified_by_display_name, #log_change, #log_deletion, #remove_blank_secure_fields, #save_and_log, #save_and_log!, #secure_fields, #update, #update!, #update_and_log, #update_and_log!

Methods included from App47Logger

clean_params, #clean_params, delete_parameter_keys, #log_controller_error, log_debug, #log_debug, log_error, #log_error, log_exception, #log_message, log_message, #log_warn, log_warn, mask_parameter_keys, #update_flash_messages

Instance Method Details

#account_smtp_configurationObject



187
188
189
190
191
192
193
194
195
196
197
198
199
200
# File 'lib/app/models/email_notification.rb', line 187

def 
  smtp = .fetch_smtp_configuration

  config = {
    address: smtp.server_name,
    port: smtp.port,
    authentication: smtp.authentication_method.to_sym,
    enable_starttls_auto: smtp.ssl.eql?(true)
  }
  config[:domain] = smtp.domain if smtp.domain.present?
  config[:user_name] = smtp.username if smtp.username.present?
  config[:password] = smtp.password if smtp.password.present?
  config
end

#account_subject_template(template_name) ⇒ Object



243
244
245
246
247
# File 'lib/app/models/email_notification.rb', line 243

def (template_name)
  .email_templates.find_by(name: template_name.to_s).subject
rescue StandardError
  nil
end

#add_attachments(attachments = nil) ⇒ Object



123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/app/models/email_notification.rb', line 123

def add_attachments(attachments = nil)
  tmp_dir = Dir.mktmpdir
  attachments.each do |attachment|
    # Create a temp directory, it'll get cleaned up in the rescue.
    tmp_file_path = "#{tmp_dir}/#{attachment.file_file_name}"
    File.open(tmp_file_path, 'w') do |f|
      f.write(URI.parse(attachment.file_url).open.read.force_encoding('utf-16').encode)
    end
    mail.attachments[attachment.file_file_name] = {
      mime_type: attachment.file_content_type,
      content: File.open(tmp_file_path).read.force_encoding('utf-16').encode
    }
  end
end

#add_notification_tracker(html_message) ⇒ Object



215
216
217
218
219
220
221
# File 'lib/app/models/email_notification.rb', line 215

def add_notification_tracker(html_message)
  tracker_url = "#{SystemConfiguration.base_url}/notifications/#{id}/img"
  return html_message if html_message.include?(tracker_url)

  image_tag = "<img style='height:0;width:0;border:none;display:none;' src='#{tracker_url}' alt=''/></body>"
  html_message.sub(%r{<\/body>}, image_tag)
end

#build_messageObject

HTMLize messages



209
210
211
212
213
# File 'lib/app/models/email_notification.rb', line 209

def build_message
  clean_message = message.strip
  clean_message = "<html><body><pre>#{clean_message}</pre></body></html>" unless clean_message.start_with?('<')
  add_notification_tracker(clean_message)
end

#default_smtp_configurationObject



202
203
204
# File 'lib/app/models/email_notification.rb', line 202

def default_smtp_configuration
  SystemConfiguration.smtp_configuration
end

#deliver_message!Object

Add a file as an attachment to this email notification.

Expecting a path to the file, not the file or data itself. TODO consider how to handle a file object or data object.

Once you have called this method, the file is stored via PaperClip and does not need to stay persistant through email delivery. You can delete it after telling the EmailNotification to send the notification.

def add_file(file)

# Make sure we are saved
save! unless persisted?
attachment = EmailNotificationAttachment.new email_notification: self
attachment.file = open(file)
attachment.save!

end



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/app/models/email_notification.rb', line 69

def deliver_message!
  mail = Mail.new
  # Set the from line
  address = from_address
  mail.from = address
  self.from = address
  # Set the sender line
  address = sender_address
  mail.sender = address
  self.sender = address
  # Set the reply to
  address = reply_to_address
  if address.present?
    self.reply_to = address
    mail.reply_to = address
    mail.sender = address
  end

  # Set the to address
  mail.to = to

  # Set the cc line
  mail.cc = cc unless cc.nil?

  # Set the subject line
  mail.subject = subject

  # set the message body and send
  html_message = build_message
  mail.html_part do
    content_type 'text/html; charset=UTF-8'
    body html_message
  end

  # Add the attachments, if there are any. If not, none are added.
  add_attachments(attachments) if defined?(attachments)

  # Setup the delivery method for this message only.
  if 'test'.eql?(ENV['RAILS_ENV'])
    mail.delivery_method :test
  else
    mail.delivery_method :smtp, smtp_configuration
  end

  mail.header['X-Mailgun-Native-Send'] = 'yes' if SystemConfiguration.mail_gun_configured?
  # Deliver it
  mail.deliver
rescue StandardError => error
  # We are catching and rethrowing this only to allow the temp directory to be cleaned up in the ensure block
  raise error
ensure
  FileUtils.remove_entry_secure(tmp_dir) if defined?(tmp_dir) && tmp_dir.present?
end

#from_addressObject

From address



153
154
155
156
157
158
159
160
161
162
# File 'lib/app/models/email_notification.rb', line 153

def from_address
  return from if from.present?

  address = SystemConfiguration.default_email
  if .present?
     = .fetch_smtp_configuration
    address = .email_address if .use?
  end
  address
end

#from_template(template_name, locals = {}) ⇒ Object

has_many :attachments, class_name: ‘EmailNotificationAttachment’, dependent: :destroy



46
47
48
49
# File 'lib/app/models/email_notification.rb', line 46

def from_template(template_name, locals = {})
  super
  self.subject = subject_from_template(template_name, locals)
end

#reply_to_addressObject

Reply to address



167
168
169
170
171
172
173
174
175
176
# File 'lib/app/models/email_notification.rb', line 167

def reply_to_address
  return reply_to if reply_to.present?

  address = nil
  unless .nil?
    smtp = .fetch_smtp_configuration
    address = smtp.reply_to_address if smtp.use? && !smtp.reply_to_address.nil? && !smtp.reply_to_address.empty?
  end
  address
end

#sender_addressObject

sender address



141
142
143
144
145
146
147
148
# File 'lib/app/models/email_notification.rb', line 141

def sender_address
  address = SystemConfiguration.support_email
  if .present?
     = .fetch_smtp_configuration
    address = .username if .use?
  end
  address
end

#smtp_configurationObject

SMTP Configuration



181
182
183
184
185
# File 'lib/app/models/email_notification.rb', line 181

def smtp_configuration
  .get_smtp_configuration.use? ?  : default_smtp_configuration
rescue StandardError
  default_smtp_configuration
end

#subject_from_haml_text(haml_text, locals) ⇒ Object



223
224
225
226
227
# File 'lib/app/models/email_notification.rb', line 223

def subject_from_haml_text(haml_text, locals)
  locals[:base_url] = SystemConfiguration.base_url
  haml_engine = Haml::Engine.new(haml_text)
  self.subject = haml_engine.render(Object.new, stringify_all(locals))
end

#subject_from_liquid_text(liquid_text, locals) ⇒ Object



229
230
231
# File 'lib/app/models/email_notification.rb', line 229

def subject_from_liquid_text(liquid_text, locals)
  self.subject = render_liquid_text(liquid_text, locals)
end

#subject_from_template(template_name, locals) ⇒ Object



233
234
235
236
237
238
239
240
241
# File 'lib/app/models/email_notification.rb', line 233

def subject_from_template(template_name, locals)
  subject = (template_name) || Template.from_file(template_name, prefix: 'subject')
  if subject.present?
    subject_from_liquid_text(subject, locals)
  else
    subject = Template.from_file(template_name, format: 'haml', prefix: 'subject')
    subject.present? ? subject_from_haml_text(subject, locals) : nil
  end
end