refactor(email): Move LeadmailDelivery to app/mailers for auto-loading
Some checks failed
Lock Threads / action (push) Has been cancelled
Some checks failed
Lock Threads / action (push) Has been cancelled
This commit is contained in:
105
app/mailers/leadmail_delivery.rb
Normal file
105
app/mailers/leadmail_delivery.rb
Normal file
@@ -0,0 +1,105 @@
|
||||
class LeadmailDelivery
|
||||
attr_reader :settings
|
||||
|
||||
def initialize(settings)
|
||||
@settings = settings
|
||||
end
|
||||
|
||||
def deliver!(message)
|
||||
payload = build_payload(message)
|
||||
response = http_client.post('/emails/send', payload)
|
||||
|
||||
unless response.success?
|
||||
raise LeadmailDeliveryError, "LeadMail API error: #{response.status} - #{response.body}"
|
||||
end
|
||||
|
||||
response_data = JSON.parse(response.body)
|
||||
message.header['X-LeadMail-Log-ID'] = response_data.dig('data', 'log_id')
|
||||
Rails.logger.info("Email sent via LeadMail: log_id=#{response_data.dig('data', 'log_id')}, to=#{message.to.inspect}")
|
||||
response
|
||||
rescue StandardError => e
|
||||
Rails.logger.error("LeadMail delivery failed: #{e.message}\nPayload: #{payload.inspect}")
|
||||
raise
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def build_payload(message)
|
||||
{
|
||||
from: extract_from(message),
|
||||
to: extract_recipients(message.to),
|
||||
cc: extract_recipients(message.cc),
|
||||
bcc: extract_recipients(message.bcc),
|
||||
reply_to: extract_reply_to(message),
|
||||
subject: message.subject,
|
||||
html_body: html_body(message),
|
||||
text_body: text_body(message),
|
||||
attachments: extract_attachments(message),
|
||||
options: {
|
||||
on_verification_failure: 'strip',
|
||||
allow_disposable: false
|
||||
}
|
||||
}.compact
|
||||
end
|
||||
|
||||
def extract_from(message)
|
||||
from_address = message.from&.first
|
||||
from_display = message[:from]&.display_names&.first
|
||||
|
||||
{
|
||||
email: from_address,
|
||||
name: from_display
|
||||
}.compact
|
||||
end
|
||||
|
||||
def extract_recipients(addresses)
|
||||
return nil if addresses.blank?
|
||||
|
||||
Array(addresses).map { |email| { email: email } }
|
||||
end
|
||||
|
||||
def extract_reply_to(message)
|
||||
reply_to_address = message.reply_to&.first
|
||||
return nil if reply_to_address.blank?
|
||||
|
||||
{ email: reply_to_address }
|
||||
end
|
||||
|
||||
def html_body(message)
|
||||
return message.html_part.body.to_s if message.html_part.present?
|
||||
return message.body.to_s if message.content_type&.start_with?('text/html')
|
||||
|
||||
nil
|
||||
end
|
||||
|
||||
def text_body(message)
|
||||
return message.text_part.body.to_s if message.text_part.present?
|
||||
return message.body.to_s if message.content_type&.start_with?('text/plain')
|
||||
|
||||
nil
|
||||
end
|
||||
|
||||
def extract_attachments(message)
|
||||
return nil if message.attachments.blank?
|
||||
|
||||
message.attachments.map do |attachment|
|
||||
{
|
||||
filename: attachment.filename,
|
||||
mime_type: attachment.mime_type || 'application/octet-stream',
|
||||
content: Base64.strict_encode64(attachment.body.to_s)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def http_client
|
||||
@http_client ||= Faraday.new(
|
||||
url: settings[:api_url],
|
||||
headers: {
|
||||
'Authorization' => "Bearer #{settings[:token]}",
|
||||
'Content-Type' => 'application/json'
|
||||
}
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
class LeadmailDeliveryError < StandardError; end
|
||||
Reference in New Issue
Block a user