Aggiunge IMAP bounce e flag email non valide nel CRM.
Permette di leggere i bounce dalla stessa MailIdentity SMTP, aggiornare le email in anagrafica e saltare gli indirizzi invalidi nei mailing. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -9,15 +9,30 @@ class MailIdentity < ApplicationRecord
|
||||
|
||||
ENCRYPTIONS = Catalog::MAIL_ENCRYPTIONS.keys.freeze
|
||||
|
||||
# Mapping host SMTP → IMAP tipici dei provider usati in produzione.
|
||||
IMAP_HOST_HINTS = {
|
||||
"aruba.it" => "imaps.aruba.it",
|
||||
"smtps.aruba.it" => "imaps.aruba.it",
|
||||
"smtp.aruba.it" => "imaps.aruba.it",
|
||||
"gmail.com" => "imap.gmail.com",
|
||||
"smtp.gmail.com" => "imap.gmail.com",
|
||||
"outlook.com" => "outlook.office365.com",
|
||||
"smtp.office365.com" => "outlook.office365.com"
|
||||
}.freeze
|
||||
|
||||
validates :name, :from_name, :from_email, :smtp_host, :smtp_port, presence: true
|
||||
validates :from_email, format: { with: URI::MailTo::EMAIL_REGEXP }
|
||||
validates :reply_to, format: { with: URI::MailTo::EMAIL_REGEXP }, allow_blank: true
|
||||
validates :smtp_port, numericality: { in: 1..65535 }
|
||||
validates :imap_port, numericality: { in: 1..65535 }, allow_nil: true
|
||||
validates :encryption, inclusion: { in: ENCRYPTIONS }
|
||||
validates :smtp_authentication, inclusion: { in: Catalog::MAIL_AUTH_METHODS.keys }
|
||||
validate :encryption_matches_port
|
||||
|
||||
before_validation :apply_imap_defaults
|
||||
|
||||
scope :active, -> { where(active: true) }
|
||||
scope :imap_enabled, -> { where(imap_enabled: true) }
|
||||
scope :ordered, -> { order(:name) }
|
||||
|
||||
def from_header
|
||||
@@ -42,8 +57,56 @@ class MailIdentity < ApplicationRecord
|
||||
settings
|
||||
end
|
||||
|
||||
def imap_username
|
||||
smtp_username.presence || from_email
|
||||
end
|
||||
|
||||
def effective_imap_host
|
||||
imap_host.presence || inferred_imap_host
|
||||
end
|
||||
|
||||
def effective_imap_port
|
||||
(imap_port.presence || 993).to_i
|
||||
end
|
||||
|
||||
def imap_ready?
|
||||
imap_enabled? && effective_imap_host.present? && effective_imap_port.positive?
|
||||
end
|
||||
|
||||
def imap_settings
|
||||
{
|
||||
address: effective_imap_host,
|
||||
port: effective_imap_port,
|
||||
ssl: true,
|
||||
user_name: imap_username,
|
||||
password: smtp_password
|
||||
}
|
||||
end
|
||||
|
||||
def inferred_imap_host
|
||||
host = smtp_host.to_s.downcase.strip
|
||||
return if host.blank?
|
||||
|
||||
IMAP_HOST_HINTS.each do |needle, imap|
|
||||
return imap if host == needle || host.end_with?(".#{needle}") || host.include?(needle)
|
||||
end
|
||||
|
||||
# Fallback generico: smtp.X → imap.X, smtps.X → imaps.X
|
||||
if host.start_with?("smtps.")
|
||||
host.sub(/\Asmtps\./, "imaps.")
|
||||
elsif host.start_with?("smtp.")
|
||||
host.sub(/\Asmtp\./, "imap.")
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def apply_imap_defaults
|
||||
self.imap_port = 993 if imap_port.blank?
|
||||
self.imap_enabled = true if imap_enabled.nil?
|
||||
self.imap_host = inferred_imap_host if imap_host.blank? && inferred_imap_host.present?
|
||||
end
|
||||
|
||||
def encryption_matches_port
|
||||
return if smtp_port.blank? || encryption.blank?
|
||||
|
||||
|
||||
Reference in New Issue
Block a user