///|
pub(all) enum MailCategory {
Personal
Newsletter
Notification
Security
Billing
BuildSystem
CalendarInvite
Bounce
UnknownCategory
} derive(Eq, Debug)
///|
pub fn classify_message(message : MailMessage) -> MailCategory {
let subject = lower_ascii(message.subject)
let from = lower_ascii(join_mailboxes_for_classification(message.from))
let body = lower_ascii(
plain_text(message) + " " + strip_html(html_text(message)),
)
if is_bounce(message) {
Bounce
} else if subject.contains("invoice") || from.contains("billing") {
Billing
} else if subject.contains("password") ||
from.contains("security") ||
body.contains("reset your password") {
Security
} else if subject.contains("build failed") || from.contains("ci@") {
BuildSystem
} else if from.contains("newsletter") || has_list_unsubscribe(message) {
Newsletter
} else if from.contains("calendar") ||
has_attachment_named(message, "invite.ics") {
CalendarInvite
} else if from.contains("support") || subject.contains("ticket") {
Notification
} else if message.from.length() > 0 &&
(message.to.length() > 0 || message.cc.length() > 0) {
Personal
} else {
UnknownCategory
}
}
///|
fn join_mailboxes_for_classification(items : Array[Address]) -> String {
let mut out = ""
for item in items {
out = out + " " + item.display + " " + item.mailbox
}
out
}
///|
pub fn category_name(category : MailCategory) -> String {
match category {
Personal => "personal"
Newsletter => "newsletter"
Notification => "notification"
Security => "security"
Billing => "billing"
BuildSystem => "build-system"
CalendarInvite => "calendar-invite"
Bounce => "bounce"
UnknownCategory => "unknown"
}
}
///|
pub fn category_counts(messages : Array[MailMessage]) -> Array[(String, Int)] {
let names = [
"personal", "newsletter", "notification", "security", "billing", "build-system",
"calendar-invite", "bounce", "unknown",
]
let out : Array[(String, Int)] = []
for name in names {
let mut count = 0
for message in messages {
if category_name(classify_message(message)) == name {
count = count + 1
}
}
out.push((name, count))
}
out
}
///|
pub fn messages_by_category(
messages : Array[MailMessage],
category : MailCategory,
) -> Array[MailMessage] {
let out : Array[MailMessage] = []
for message in messages {
if classify_message(message) == category {
out.push(message)
}
}
out
}