type.inbound
// Looking for Punchbowl phrasing in all body threads
and (
strings.icontains(body.current_thread.text, "punchbowl")
// Look for alt text in HTML for standardized Punchbowl formatting if string is not avail.
or strings.icontains(body.html.raw, 'alt="Punchbowl"')
// image sourced from punchbowl
or any(html.xpath(body.html, '//img/@src').nodes,
strings.parse_url(.raw).domain.domain == "static.punchbowl.com"
and strings.icontains(strings.parse_url(.raw).path, '/invitation')
)
)
// Phrasing is typically "You're invited"
and (
strings.icontains(body.current_thread.text, "you're invited")
//
// This rule makes use of a beta feature and is subject to change without notice
// using the beta feature in custom rules is not suggested until it has been formally released
//
or (
strings.icontains(beta.ocr(file.message_screenshot()).text,
"you're invited",
"open me",
"manage invitation"
)
and regex.icontains(body.current_thread.text, 'don.t want .{1,40}\?')
)
or any([
html.xpath(body.html,
'//a//img[contains(@src, "btn_open_invitation")]'
).nodes,
html.xpath(body.html,
'//a//img[contains(@src, "btn_open_save_the_date")]'
).nodes,
],
any(.,
regex.icontains(.inner_text,
'(?:open|save).{0,10}(?:invitation|the date)'
)
)
)
)
// Legitimate sender will be from punchbowl, negating known non-associated domains.
and not sender.email.domain.root_domain in ("punchbowl.com", "punchbowl.news")
// Capping length to limit FP's
and length(body.current_thread.text) < 1500
Playground
Test against your own EMLs or sample data.