class ActionMailerKafka::DeliveryMethod
Constants
- SUPPORTED_MULTIPART_MIME_TYPES
Attributes
settings[RW]
Public Class Methods
new(**params)
click to toggle source
settings params allow you to pass in
-
Your Kafka publisher
With this option, you pass an instance of Kafka Publisher, which inherit from our ActionMailerKafka::BasesProducer or at least support the method `publish` with the same parameters. After that, your should be as below: config.action_mailer.eh_mailer_settings = {
kafka_mail_topic: 'YourKafkaTopic', kafka_publisher: PublisherKlass.new
} and the data would go through your publisher instance
-
Your kafka client info
With this option, the library will generate a kafka instance for you: config.action_mailer.eh_mailer_settings = {
kafka_mail_topic: 'YourKafkaTopic', kafka_client_info: { seed_brokers: ['localhost:9090'], logger: logger, ssl_ca_cert: '/path/to/cert' # For more option on what to pass here, see https://github.com/zendesk/ruby-kafka/blob/master/lib/kafka/client.rb#L20 }
}
Other settings params:
- raise_on_delivery_error - logger - fallback + fallback_delivery_method + fallback_delivery_method_settings }
# File lib/action_mailer_kafka/delivery_method.rb, line 38 def initialize(**params) @settings = params # Optional config @logger = settings[:logger] @raise_on_delivery_error = settings[:raise_on_delivery_error] # General configuration @service_name = settings[:service_name] || '' @mailer_topic_name = settings.fetch(:kafka_mail_topic) @kafka_publisher = settings[:kafka_publisher] || ActionMailerKafka::BaseProducer.new( logger: @logger, kafka_client_info: settings[:kafka_client_info] ) # Fallback configuration @fallback = settings[:fallback] if @fallback @fallback_delivery_method = Mail::Configuration.instance.lookup_delivery_method( @fallback.fetch(:fallback_delivery_method) ).new( @fallback.fetch(:fallback_delivery_method_settings) ) end rescue KeyError => e raise RequiredParamsError.new(settings, e.message) end
Public Instance Methods
deliver!(mail)
click to toggle source
# File lib/action_mailer_kafka/delivery_method.rb, line 64 def deliver!(mail) mail_data = construct_mail_as_kafka_message(mail) @kafka_publisher.publish(mail_data, construct_message_key, @mailer_topic_name) rescue Kafka::Error => e error_msg = "Fail to send email into Kafka due to: #{e.message}. Delivered using fallback method" @logger&.error(error_msg) @fallback_delivery_method.deliver!(mail) if @fallback raise KafkaOperationError, error_msg if @raise_on_delivery_error rescue StandardError => e error_msg = "Fail to send email due to: #{e.message}" @logger&.error(error_msg) raise ParsingOperationError, error_msg if @raise_on_delivery_error end
Private Instance Methods
construct_attachments(mail)
click to toggle source
# File lib/action_mailer_kafka/delivery_method.rb, line 113 def construct_attachments(mail) mail.attachments.map { |part| convert_attachment part } end
construct_custom_mail_header(mail)
click to toggle source
# File lib/action_mailer_kafka/delivery_method.rb, line 96 def construct_custom_mail_header(mail) result = { custom_headers: {} } mail.header_fields.each do |h| header_name = h.name # header_value = h.unparsed_value # Ideally header values should not be parsed and sent directly to the mail service # However, Field #unparsed_value is not available on Mail Gem version 2.5 and before # here header.value got its value parsed, so a string should be expected # even if you create a custom header with a hash header_value = h.value if h.field.is_a?(::Mail::OptionalField) && header_name.start_with?('X-') result[:custom_headers][header_name] = header_value end end result end
construct_mail_as_kafka_message(mail)
click to toggle source
# File lib/action_mailer_kafka/delivery_method.rb, line 80 def construct_mail_as_kafka_message(mail) general_data = { subject: mail.subject, from: mail.from, to: mail.to, cc: mail.cc, bcc: mail.bcc, mime_type: mail.mime_type, author: @service_name } general_data.merge! construct_mail_body(mail) general_data.merge! construct_custom_mail_header(mail) general_data[:attachments] = construct_attachments mail general_data.to_msgpack end
construct_mail_body(mail)
click to toggle source
# File lib/action_mailer_kafka/delivery_method.rb, line 125 def construct_mail_body(mail) if SUPPORTED_MULTIPART_MIME_TYPES.include?(mail.mime_type) { text_part: mail.text_part&.decoded, html_part: mail.html_part&.decoded } else { body: mail.body&.decoded } end end
construct_message_key()
click to toggle source
# File lib/action_mailer_kafka/delivery_method.rb, line 136 def construct_message_key # shamelessly copy from https://www.rubydoc.info/github/mikel/mail/Mail%2FUtilities:generate_message_id # because some 'mail' version doesn't have this function "<#{Mail.random_tag}@#{::Socket.gethostname}.mail>" end
convert_attachment(part)
click to toggle source
# File lib/action_mailer_kafka/delivery_method.rb, line 117 def convert_attachment(part) { content: Base64.strict_encode64(part.body.decoded), type: part.mime_type, filename: part.filename } end