#3 — Duplicate prospect handling: add_lead now checks (campaign_id, url) before insert; bulk_add_leads skips existing URLs. #8 — Atomic rate limiting: try_increment_* methods atomically check cap and increment in a single session; router uses these before send. #10 — Reply matching via Message-ID: sender generates Message-ID header, stored on OutreachAttempt; reply monitor parses In-Reply-To/References; poll_replies matches by message_id first, falls back to from_email. #11 — Save-to-campaign uses existing store results instead of re-running expensive deepDiscover. #12 — Lead status Literal type: Pydantic models enforce valid status values; backend validates via LEAD_VALID_STATUSES frozenset; frontend API typed as LeadStatus union.
This commit is contained in:
@@ -104,6 +104,8 @@ class BacklinkOutreachReplyMonitor:
|
||||
from_email = parsed_msg.get("From", "")
|
||||
subject = parsed_msg.get("Subject", "")
|
||||
received_at = parsed_msg.get("Date", "")
|
||||
in_reply_to = parsed_msg.get("In-Reply-To", "")
|
||||
references = parsed_msg.get("References", "")
|
||||
|
||||
# Extract body
|
||||
body = ""
|
||||
@@ -137,6 +139,8 @@ class BacklinkOutreachReplyMonitor:
|
||||
"body": body[:5000],
|
||||
"classification": classification,
|
||||
"received_at": received_at_iso,
|
||||
"in_reply_to": in_reply_to,
|
||||
"references": references,
|
||||
}
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to parse reply: {e}")
|
||||
|
||||
Reference in New Issue
Block a user