fix(email): skip noreply/no-reply sender addresses in IMAP and Exchange polling

linuztx committed Mar 15, 2026 at 11:27 UTC 9cf77404632616c5e52daf56ae0e60acc7c481f2
1 file changed +17
plugins/_email_integration/helpers/imap_client.py
+17
@@ -155,6 +155,8 @@ async def _fetch_single(
155 email_msg = email.message_from_bytes(email_data)
156
157 sender = _decode_header(email_msg.get("From", ""))
158 + if _is_noreply(sender):
159 + return None
160 if sender_whitelist and not _matches_whitelist(sender, sender_whitelist):
161 return None
162
@@ -219,6 +221,8 @@ async def fetch_unread_exchange(
221
222 for item in items:
223 sender = str(item.sender.email_address) if item.sender else ""
224 + if _is_noreply(sender):
225 + continue
226 if sender_whitelist and not _matches_whitelist(sender, sender_whitelist):
227 continue
228
@@ -362,6 +366,19 @@ def _decode_header(header: str) -> str:
366 return " ".join(parts)
367
368
369 +def _is_noreply(sender: str) -> bool:
370 + addr = sender.lower()
371 + match = re.search(r"<([^>]+)>", addr)
372 + if match:
373 + addr = match.group(1)
374 + local = addr.split("@")[0] if "@" in addr else addr
375 + return local in (
376 + "noreply", "no-reply", "no_reply",
377 + "donotreply", "do-not-reply", "do_not_reply",
378 + "mailer-daemon", "postmaster",
379 + )
380 +
381 +
382 def _matches_whitelist(sender: str, whitelist: list[str]) -> bool:
383 sender_lower = sender.lower()
384 for pattern in whitelist: