type.inbound
// we need at least two threads
and length(body.previous_threads) > 1
// oldest thread is invoice/payment related
and (
any(ml.nlu_classifier(body.previous_threads[length(body.previous_threads)-1].text, subject=body.previous_threads[length(body.previous_threads)-1].subject.base).tags, .name in ("invoice", "payment") and .confidence != "low")
or any(ml.nlu_classifier(body.previous_threads[length(body.previous_threads)-1].text, subject=body.previous_threads[length(body.previous_threads)-1].subject.base).topics, .name in ("Request to View Invoice", "Payment Information") and .confidence != "low")
)
// second to oldest thread is invoice/payment related
and (
any(ml.nlu_classifier(body.previous_threads[length(body.previous_threads)-2].text, subject=body.previous_threads[length(body.previous_threads)-2].subject.base).tags, .name in ("invoice", "payment") and .confidence != "low")
or any(ml.nlu_classifier(body.previous_threads[length(body.previous_threads)-2].text, subject=body.previous_threads[length(body.previous_threads)-2].subject.base).topics, .name in ("Request to View Invoice", "Payment Information") and .confidence != "low")
)
// each of the two oldest threads have 1 or less recipients (sometimes the "to" header is missing)
and length(body.previous_threads[length(body.previous_threads) - 1].recipients.to) <= 1
and length(body.previous_threads[length(body.previous_threads) - 2].recipients.to) <= 1
// at least one party in the two oldest threads is missing an email
and (
body.previous_threads[length(body.previous_threads) - 1].sender.email.email == ""
or body.previous_threads[length(body.previous_threads) - 1].recipients.to[0].email.email == ""
or body.previous_threads[length(body.previous_threads) - 2].sender.email.email == ""
or body.previous_threads[length(body.previous_threads) - 2].recipients.to[0].email.email == ""
)
// an org vip sent/received messages
and any($org_vips,
( body.previous_threads[length(body.previous_threads) - 1].recipients.to[0].display_name == .display_name
and body.previous_threads[length(body.previous_threads) - 2].sender.display_name == .display_name )
or ( body.previous_threads[length(body.previous_threads) - 1].sender.display_name == .display_name
and body.previous_threads[length(body.previous_threads) - 2].recipients.to[0].display_name == .display_name )
)
// the VIP is no longer in the current message
and not any(flatten([recipients.to, recipients.cc, recipients.bcc]),
any($org_vips,
.email != ""
and strings.icontains(..email.email, .email)
and (
( body.previous_threads[length(body.previous_threads) - 1].recipients.to[0].display_name == .display_name
and body.previous_threads[length(body.previous_threads) - 2].sender.display_name == .display_name )
or ( body.previous_threads[length(body.previous_threads) - 1].sender.display_name == .display_name
and body.previous_threads[length(body.previous_threads) - 2].recipients.to[0].display_name == .display_name )
)))
// not from authorized senders on the org's domain
and not (sender.email.domain.domain in $org_domains and coalesce(headers.auth_summary.dmarc.pass, false))
Playground
Test against your own EMLs or sample data.