Extraction du mapping des metadonnées dans EmailAction::MetedataMapping

This commit is contained in:
Jérémy Lecour 2021-01-20 13:46:45 +01:00 committed by Jérémy Lecour
parent c12bf5af8f
commit f99723c1f7
4 changed files with 89 additions and 70 deletions

View file

@ -46,6 +46,14 @@ class Email
mailing_list
end
def header_values(header_name)
headers.select { |header|
header["name"] == header_name
}.filter_map { |header|
header["value"]
}
end
def self.find(id)
EmailRepository.new.find(id)
end

View file

@ -0,0 +1,17 @@
# frozen_string_literal: true
module EmailAction
class IssueMapping < Base
def process(email)
values = ["X-Ticket-Id", "X-Issue-Id"].filter_map { |header_name|
email.header_values(header_name)
}.flatten.uniq
email.tickets = values
email
end
end
end

View file

@ -0,0 +1,63 @@
# frozen_string_literal: true
module EmailAction
class MetadataMapping < Base
attr_accessor :metadata_mapping_class
def initialize(
metadata_mapping_class: ::MetadataMapping)
@metadata_mapping_class = metadata_mapping_class
end
def process(email)
metadata_inputs = metadata_inputs(email)
metadata = metadata_mapping_class.where(input: metadata_inputs).all
email.clients = metadata.filter_map(&:entity).uniq
email.servers = metadata.filter_map(&:server).uniq
email
rescue => ex
binding.pry
end
def metadata_inputs(email)
inputs = []
# add mail addresses and hostnames from headers
inputs << ["To", "Delivered-To", "X-Original-To", "From", "Subject"].filter_map { |header_name|
email.header_values(header_name)
}.flatten.filter_map() { |header_value|
keep_email_and_hostnames(header_value)
}.flatten.filter_map() { |value|
clean_subdomains(value)
}.flatten
# add other values from headers
inputs << email.header_values("X-Client-Id")
inputs.flatten.uniq
end
def keep_email_and_hostnames(string)
pattern = /\b((?:([-a-zA-Z0-9\._]+)@)?((?:[-a-zA-Z0-9\._]*)(?:\.[a-z]{2,})))\b/
results = string.scan(pattern)
if results.present?
results.map(&:first)
end
end
def clean_subdomains(value)
[
[/[-a-zA-Z0-9\._]+@([-a-zA-Z0-9]+).evolix.net/, '@\1']
].filter_map { |item|
if value.match?(item[0])
value.gsub!(item[0], item[1])
else
value
end
}
end
end
end

View file

@ -2,16 +2,13 @@
class EmailImporter
attr_accessor :email_class
attr_accessor :metadata_mapping_class
attr_accessor :html_to_text_class
def initialize(
email_class: Email,
metadata_mapping_class: MetadataMapping,
html_to_text_class: Rails.configuration.html_to_text_class)
@email_class = email_class
@metadata_mapping_class = metadata_mapping_class
@html_to_text_class = html_to_text_class
end
@ -24,12 +21,7 @@ class EmailImporter
delivered_to: delivered_to(mail),
from: mail.from,
plain_body: text_plain_body(mail),
headers: hashed_headers(mail),
cron: sent_by_cron?(mail),
mailing_list: mailing_list?(mail),
clients: clients(mail),
servers: servers(mail),
tickets: tickets(mail)
headers: hashed_headers(mail)
)
rescue => ex
binding.pry
@ -70,27 +62,6 @@ class EmailImporter
}
end
def sent_by_cron?(mail)
(mail.subject.present? && mail.subject.match?(/cron/i)) \
|| mail.header["X-Cron-Env"].present?
end
def mailing_list?(mail)
mail.header["List-Unsubscribe"].present?
end
def clients(mail)
metadata(mail).filter_map(&:entity).uniq
end
def servers(mail)
metadata(mail).filter_map(&:server).uniq
end
def tickets(mail)
values_from_header(header: mail.header["X-Ticket-Id"])
end
def values_from_header(header:, default: [])
if header.respond_to?(:map)
header.map(&:value)
@ -102,44 +73,4 @@ class EmailImporter
default
end
end
def metadata(mail)
@metadata ||= metadata_mapping_class.where(input: metadata_inputs(mail)).all
end
def metadata_inputs(mail)
inputs = []
# add mail addresses and hostnames from headers
inputs << ["To", "Delivered-To", "X-Original-To", "From", "Subject"].filter_map { |header_name|
mail.header[header_name]
}.flatten.map(&:value).filter_map() { |header_value|
keep_email_and_hostnames(header_value)
}.flatten.filter_map() { |value|
clean_subdomains(value)
}.flatten
# add other values from headers
inputs << mail.header["X-Client-Id"]
inputs.uniq
end
def keep_email_and_hostnames(string)
pattern = /\b((?:([-a-zA-Z0-9\._]+)@)?((?:[-a-zA-Z0-9\._]*)(?:\.[a-z]{2,})))\b/
results = string.scan(pattern)
if results.present?
results.map(&:first)
end
end
def clean_subdomains(value)
[
[/[-a-zA-Z0-9\._]+@([-a-zA-Z0-9]+).evolix.net/, '@\1']
].filter_map { |item|
if value.match?(item[0])
value.gsub!(item[0], item[1])
else
value
end
}
end
end