feat(onboarding): detect email provider from domain MX records (#14571)
During account enrichment, WebsiteBrandingService now probes the signup domain's MX records to infer whether email is hosted on Google Workspace or Microsoft 365, adding `email_provider` (`google`/`microsoft`/`nil`) to `brand_info`. Matching is anchored on a label boundary so lookalike domains aren't misclassified, and lookup failures fall back to `nil`. This lets downstream UI suggest the right mailbox integration (Gmail vs Outlook).
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
require 'resolv'
|
||||
|
||||
class WebsiteBrandingService
|
||||
include SocialLinkParser
|
||||
|
||||
@@ -24,7 +26,8 @@ class WebsiteBrandingService
|
||||
colors: extract_colors(doc),
|
||||
logos: extract_logos(doc),
|
||||
socials: build_socials(links),
|
||||
email: @email
|
||||
email: @email,
|
||||
email_provider: detect_email_provider
|
||||
})
|
||||
rescue StandardError => e
|
||||
Rails.logger.error "[WebsiteBranding] #{e.message}"
|
||||
@@ -104,6 +107,37 @@ class WebsiteBrandingService
|
||||
rescue URI::InvalidURIError
|
||||
nil
|
||||
end
|
||||
|
||||
GOOGLE_MX_DOMAINS = %w[google.com googlemail.com].freeze
|
||||
MICROSOFT_MX_DOMAINS = %w[outlook.com].freeze
|
||||
|
||||
# Probes the domain's MX records to infer the mailbox provider, returning
|
||||
# 'google' or 'microsoft' (matching Channel::Email#provider) or nil when unknown.
|
||||
def detect_email_provider
|
||||
hosts = mx_records
|
||||
return 'google' if mx_hosted_by?(hosts, GOOGLE_MX_DOMAINS)
|
||||
return 'microsoft' if mx_hosted_by?(hosts, MICROSOFT_MX_DOMAINS)
|
||||
|
||||
nil
|
||||
end
|
||||
|
||||
# Matches on the registrable domain of the MX host (anchored on a label
|
||||
# boundary) so lookalikes like "notgoogle.com" don't get misclassified.
|
||||
def mx_hosted_by?(hosts, provider_domains)
|
||||
hosts.any? do |host|
|
||||
provider_domains.any? { |domain| host == domain || host.end_with?(".#{domain}") }
|
||||
end
|
||||
end
|
||||
|
||||
def mx_records
|
||||
Resolv::DNS.open do |resolver|
|
||||
resolver.timeouts = 5
|
||||
resolver.getresources(@domain, Resolv::DNS::Resource::IN::MX).map { |record| record.exchange.to_s.downcase }
|
||||
end
|
||||
rescue StandardError => e
|
||||
Rails.logger.error "[WebsiteBranding] MX probe failed for #{@domain}: #{e.message}"
|
||||
[]
|
||||
end
|
||||
end
|
||||
|
||||
WebsiteBrandingService.prepend_mod_with('WebsiteBrandingService')
|
||||
|
||||
@@ -58,6 +58,7 @@ module Enterprise::WebsiteBrandingService
|
||||
socials: brand['socials'] || [],
|
||||
links: brand['links'],
|
||||
email: @email,
|
||||
email_provider: detect_email_provider,
|
||||
industries: brand.dig('industries', 'eic') || [],
|
||||
stock: brand['stock'],
|
||||
is_nsfw: brand['is_nsfw'] || false
|
||||
|
||||
Reference in New Issue
Block a user