Module: EmailEvents::Mailer

Defined in:
lib/email_events/mailer.rb

Class Method Summary collapse

Class Method Details

.included(base) ⇒ Object



3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
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
# File 'lib/email_events/mailer.rb', line 3

def self.included(base)
  base.class_eval do
    # whether or not to track the email and handle events for the email
    class_attribute :event_handler
    # additional metadata to store along the email, which we can pull up again when an event occurs (JSON format)
    class_attribute :tracked_data_method

    # an alternative class (generally, a subclass) instead of SentEmailData - eg. to perform validations on the
    # custom tracked_metadata
    class_attribute :sent_email_data_class

    after_action :__track_data_in_header

    protected
    def self.on_event(event_handler)
      self.event_handler = event_handler
    end

    def self.track_data(tracked_data_method, attrs = {})
      self.tracked_data_method = tracked_data_method
      self.sent_email_data_class = attrs[:class] if attrs.has_key? :class
    end

    def self.__track_data?
      # track the sent email if there's either an event handler or a custom track data method
      self.event_handler.present? || self.tracked_data_method.present?
    end

    def __track_data_in_header
      return unless self.class.__track_data?

      EmailEvents::Service::TrackDataInHeader.call(
        mailer: self,
        sent_email_data_class: sent_email_data_class || EmailEvents::SentEmailData,
        data: __tracked_data
      )
    end

    def __tracked_data
      return nil if tracked_data_method.nil?

      if tracked_data_method.is_a? Symbol
        self.send tracked_data_method
      else
        tracked_data_method.call
      end
    end

    def __handle_event(event_data, email_data)
      return if event_handler.nil?

      if event_handler.is_a? Symbol
        self.send event_handler, event_data, email_data
      else
        event_handler.call event_data, email_data
      end
    end

    # pry into the deliver_mail method so as to intercept the SMTP response and
    # parse out the provider message id
    singleton_class.send(:alias_method, :base_deliver_mail, :deliver_mail)
    def self.deliver_mail(message, &block)
      response = base_deliver_mail(message, &block)

      # no provider id to parse if no adapter has been set, or not tracking for this mailer
      return response if EmailEvents.adapter.nil? || !self.__track_data?

      # response won't be the smtp result unless the return_response setting is flagged on
      # (but allow it for TestMailer in test environments)
      unless (!Rails.configuration.action_mailer.smtp_settings.nil? && Rails.configuration.action_mailer.smtp_settings[:return_response]) ||
             Rails.env.test?
        raise 'Email events are enabled for this mailer, but you haven\'t turned on return_response = true in your smtp settings'
      end

      EmailEvents::Service::ParseSmtpResponseForProviderId.call(
        mail_message: message,
        raw_response: response,
        sent_email_data_class: sent_email_data_class || EmailEvents::SentEmailData,
      )
      response
    end
  end
end