fix(hausmeister): Booking.com Marketing-Mails filtern, Mail-Dedup-Race beheben
Genius-/Rabatt-Mails von noreply@booking.com waren als wichtig markiert und wurden stündlich erneut gemeldet, weil seen_mails durch State-Overwrite verloren ging.
This commit is contained in:
parent
0c5a9d73a6
commit
c19a4f654f
2 changed files with 37 additions and 5 deletions
|
|
@ -199,6 +199,23 @@ MARKETING_FROM_PATTERNS = [
|
|||
"promotion@", "promo@", "no-reply@mail.",
|
||||
]
|
||||
|
||||
# Booking.com: noreply@ mischt echte Buchungsmails mit Genius-/Rabatt-Spam.
|
||||
BOOKING_REAL_SUBJECT = [
|
||||
"confirmation", "confirmed", "bestaetigung", "bestätigung", "buchung",
|
||||
"reservation", "reservierung", "booking number", "buchungsnummer",
|
||||
"cancelled", "canceled", "storn", "modified", "geändert", "geaendert",
|
||||
"new message", "neue nachricht", "guest message", "nachricht von",
|
||||
"payment", "zahlung", "invoice", "rechnung", "receipt", "beleg",
|
||||
"check-in", "checkin", "pin code", "türcode", "tuercode", "door code",
|
||||
"cancellation", "refund", "erstattung",
|
||||
]
|
||||
BOOKING_MARKETING_SUBJECT = [
|
||||
"genius", "discount", "rabatt", "deal", "angebot", "% off", "%off",
|
||||
"extending", "fancy", "inspired", "wishlist", "save on", "sparen",
|
||||
"reminder:", "ready to use", "special offer", "last chance",
|
||||
"you might like", "entdecken", "explore", "trip ideas",
|
||||
]
|
||||
|
||||
|
||||
def _is_marketing_mail(frm_lower: str) -> bool:
|
||||
"""Werbemails von sonst wichtigen Absendern (z.B. booking.com campaign@)."""
|
||||
|
|
@ -210,6 +227,19 @@ def _is_spam_sender(frm_lower: str) -> bool:
|
|||
return any(s in frm_lower for s in SPAM_SENDERS)
|
||||
|
||||
|
||||
def _is_booking_noise(frm_lower: str, subj_lower: str) -> bool:
|
||||
"""Booking.com Marketing ausfiltern; echte Buchungs-/Gast-Mails behalten."""
|
||||
if "booking.com" not in frm_lower:
|
||||
return False
|
||||
if any(p in subj_lower for p in BOOKING_REAL_SUBJECT):
|
||||
return False
|
||||
if any(p in subj_lower for p in BOOKING_MARKETING_SUBJECT):
|
||||
return True
|
||||
if "noreply@" in frm_lower or "campaign@" in frm_lower or "email.campaign@" in frm_lower:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def get_important_mails(hours: int = 24) -> list[dict]:
|
||||
"""Mails von wichtigen Absendern (Bank, Hoster, etc.), Spam-Sender ausgefiltert."""
|
||||
m = _connect()
|
||||
|
|
@ -226,10 +256,13 @@ def get_important_mails(hours: int = 24) -> list[dict]:
|
|||
parsed = _parse_mail(msg_data)
|
||||
if parsed:
|
||||
frm_lower = parsed["from"].lower()
|
||||
subj_lower = (parsed.get("subject") or "").lower()
|
||||
if _is_spam_sender(frm_lower):
|
||||
continue
|
||||
if _is_marketing_mail(frm_lower):
|
||||
continue
|
||||
if _is_booking_noise(frm_lower, subj_lower):
|
||||
continue
|
||||
if any(s in frm_lower for s in IMPORTANT_SENDERS):
|
||||
results.append(parsed)
|
||||
results.reverse()
|
||||
|
|
|
|||
|
|
@ -409,8 +409,9 @@ def check_all(state: dict | None = None) -> list[str]:
|
|||
mail_client.init(cfg)
|
||||
important = mail_client.get_important_mails(hours=1)
|
||||
if important and "error" not in important[0]:
|
||||
state = _load_alert_state()
|
||||
seen = state.get("seen_mails", {})
|
||||
# Am gemeinsamen state-Objekt arbeiten (kein Reload/Zwischen-Save),
|
||||
# sonst ueberschreibt run_check_and_alert() die seen_mails wieder.
|
||||
seen = state.setdefault("seen_mails", {})
|
||||
now = datetime.now(timezone.utc).timestamp()
|
||||
|
||||
new_mails = []
|
||||
|
|
@ -422,9 +423,7 @@ def check_all(state: dict | None = None) -> list[str]:
|
|||
new_mails.append(m)
|
||||
seen[fp] = now
|
||||
|
||||
seen = {k: v for k, v in seen.items() if now - v < 172800}
|
||||
state["seen_mails"] = seen
|
||||
_save_alert_state(state)
|
||||
state["seen_mails"] = {k: v for k, v in seen.items() if now - v < 172800}
|
||||
|
||||
if new_mails:
|
||||
senders = [m["from"][:30] for m in new_mails]
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue