Module: Marketing::CustomerMatch::Hasher
- Defined in:
- app/services/marketing/customer_match/hasher.rb
Overview
Normalizes + SHA-256-hex-hashes PII for Google Customer Match upload.
Google requires client-side hashing of email/phone/name (lowercase + trim,
hex SHA-256). Email also strips dots and +tags from gmail/googlemail local
parts. Region/postal codes are sent in clear and are NOT handled here.
Mirrors the logic in Invoicing::GoogleConversionReporter#normalize_and_hash.
Class Method Summary collapse
-
.email(email, gmail_normalize: true) ⇒ String?
SHA-256 hex of the normalized email, nil if blank.
-
.name(name) ⇒ String?
SHA-256 hex of the normalized name, nil if blank.
-
.phone(phone, include_plus: true) ⇒ String?
SHA-256 hex of the normalized phone, nil if blank.
-
.sha256_hex(value) ⇒ String
Lowercase hex SHA-256.
Class Method Details
.email(email, gmail_normalize: true) ⇒ String?
Returns SHA-256 hex of the normalized email, nil if blank.
23 24 25 26 27 28 29 30 31 32 33 34 |
# File 'app/services/marketing/customer_match/hasher.rb', line 23 def email(email, gmail_normalize: true) return nil if email.blank? normalized = email.downcase.strip return nil unless normalized.count('@') == 1 # reject "a@b@c" and "no-at-sign" local, domain = normalized.split('@', 2) return nil if local.blank? || domain.blank? local = local.split('+', 2).first.delete('.') if gmail_normalize && domain.match?(/\A(gmail|googlemail)\.com\z/) sha256_hex("#{local}@#{domain}") end |
.name(name) ⇒ String?
Returns SHA-256 hex of the normalized name, nil if blank.
54 55 56 |
# File 'app/services/marketing/customer_match/hasher.rb', line 54 def name(name) name.blank? ? nil : sha256_hex(name.strip.downcase) end |
.phone(phone, include_plus: true) ⇒ String?
Returns SHA-256 hex of the normalized phone, nil if blank.
42 43 44 45 46 47 48 49 50 |
# File 'app/services/marketing/customer_match/hasher.rb', line 42 def phone(phone, include_plus: true) return nil if phone.blank? normalized = phone.strip.gsub(/[^\d+]/, '') return nil unless normalized.match?(/\A\+\d{7,15}\z/) # E.164: leading + and 7–15 digits normalized = normalized.delete('+') unless include_plus sha256_hex(normalized) end |
.sha256_hex(value) ⇒ String
Returns lowercase hex SHA-256.
60 61 62 |
# File 'app/services/marketing/customer_match/hasher.rb', line 60 def sha256_hex(value) Digest::SHA256.hexdigest(value) end |