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?, #template_from_file, #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



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

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



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

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

#add_attachments(attachments = nil) ⇒ Object



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

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



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

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



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

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



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

def default_smtp_configuration
  SystemConfiguration.smtp_configuration
end

#default_subject_template(template_name) ⇒ Object



248
249
250
251
252
# File 'lib/app/models/email_notification.rb', line 248

def default_subject_template(template_name)
  EmailTemplate.where(account: nil, name: template_name.to_s).template
rescue StandardError
  nil
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
# 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

  # 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



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

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



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

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



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

def sender_address
  address = SystemConfiguration.smtp_user_name
  unless .nil?
     = .fetch_smtp_configuration
    address = .username if .use?
  end
  address
end

#smtp_configurationObject

SMTP Configuration



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

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

#subject_from_haml_text(haml_text, locals) ⇒ Object



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

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



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

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

#subject_from_template(template_name, locals) ⇒ Object



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

def subject_from_template(template_name, locals)
  subject = (template_name) ||
            default_subject_template(template_name) ||
            template_from_file(template_name, prefix: 'subject')
  return subject_from_liquid_text(subject, locals) if subject.present?

  subject = template_from_file(template_name, format: 'haml', prefix: 'subject')
  subject_from_haml_text(subject, locals) if subject.present?
end