Revise contacts and email tools
All checks were successful
Build And Test / publish (push) Successful in 48s

This commit is contained in:
2026-01-01 15:46:44 -08:00
parent 767f076048
commit 5a9ef0e48f
8 changed files with 189 additions and 176 deletions

View File

@@ -438,19 +438,18 @@ class EmailService:
body: Optional[str] = None,
cc: Optional[list[str]] = None,
bcc: Optional[list[str]] = None,
reply_to: Optional[str] = None,
html_body: Optional[str] = None,
mailbox: Optional[str] = None,
reply_to_email_id: Optional[str] = None,
reply_mailbox: Optional[str] = None,
in_reply_to_email_id: Optional[str] = None,
in_reply_to_mailbox: Optional[str] = None,
reply_all: bool = False,
) -> OperationResult:
try:
draft_mailbox = mailbox or self._find_drafts_folder() or "Drafts"
if reply_to_email_id:
if in_reply_to_email_id:
context, error = self._get_reply_context(
reply_mailbox or "INBOX",
reply_to_email_id,
in_reply_to_mailbox or "INBOX",
in_reply_to_email_id,
reply_all,
cc,
self.settings.smtp_from_email,
@@ -482,7 +481,6 @@ class EmailService:
body=body,
cc=cc,
bcc=bcc,
reply_to=reply_to,
html_body=html_body,
in_reply_to=in_reply_to,
references=references,
@@ -513,10 +511,9 @@ class EmailService:
body: Optional[str] = None,
cc: Optional[list[str]] = None,
bcc: Optional[list[str]] = None,
reply_to: Optional[str] = None,
html_body: Optional[str] = None,
reply_to_email_id: Optional[str] = None,
reply_mailbox: Optional[str] = None,
in_reply_to_email_id: Optional[str] = None,
in_reply_to_mailbox: Optional[str] = None,
reply_all: bool = False,
) -> OperationResult:
draft_mailbox = mailbox or self._find_drafts_folder() or "Drafts"
@@ -539,10 +536,10 @@ class EmailService:
resolved_body = body if body is not None else (existing.body_text or "")
resolved_html = html_body if html_body is not None else existing.body_html
if reply_to_email_id:
if in_reply_to_email_id:
context, error = self._get_reply_context(
reply_mailbox or "INBOX",
reply_to_email_id,
in_reply_to_mailbox or "INBOX",
in_reply_to_email_id,
reply_all,
cc,
self.settings.smtp_from_email,
@@ -574,7 +571,6 @@ class EmailService:
body=resolved_body,
cc=resolved_cc,
bcc=resolved_bcc,
reply_to=reply_to,
html_body=resolved_html,
in_reply_to=in_reply_to,
references=references,
@@ -602,22 +598,21 @@ class EmailService:
body: Optional[str] = None,
cc: Optional[list[str]] = None,
bcc: Optional[list[str]] = None,
reply_to: Optional[str] = None,
html_body: Optional[str] = None,
sender_email: Optional[str] = None,
sender_name: Optional[str] = None,
in_reply_to: Optional[str] = None,
references: Optional[list[str]] = None,
reply_to_email_id: Optional[str] = None,
reply_mailbox: Optional[str] = None,
in_reply_to_email_id: Optional[str] = None,
in_reply_to_mailbox: Optional[str] = None,
reply_all: bool = False,
) -> OperationResult:
try:
if reply_to_email_id:
if in_reply_to_email_id:
resolved_name, resolved_email = self._resolve_sender(sender_email, sender_name)
context, error = self._get_reply_context(
reply_mailbox or "INBOX",
reply_to_email_id,
in_reply_to_mailbox or "INBOX",
in_reply_to_email_id,
reply_all,
cc,
resolved_email,
@@ -648,8 +643,6 @@ class EmailService:
if cc:
msg["Cc"] = ", ".join(cc)
if reply_to:
msg["Reply-To"] = reply_to
if in_reply_to:
msg["In-Reply-To"] = in_reply_to
if references:
@@ -687,6 +680,62 @@ class EmailService:
except Exception as e:
return OperationResult(success=False, message=str(e))
async def send_draft(
self,
email_id: str,
mailbox: Optional[str] = None,
) -> OperationResult:
draft_mailbox = mailbox or self._find_drafts_folder() or "Drafts"
try:
draft = self.read_email(draft_mailbox, email_id, format="both")
except Exception as e:
return OperationResult(success=False, message=str(e), id=email_id)
if not draft:
return OperationResult(
success=False,
message=f"Draft {email_id} not found in {draft_mailbox}",
id=email_id,
)
to = [addr.email for addr in draft.to_addresses]
cc = [addr.email for addr in draft.cc_addresses]
bcc = [addr.email for addr in draft.bcc_addresses]
if not to and not cc and not bcc:
return OperationResult(
success=False,
message="Draft has no recipients",
id=email_id,
)
subject = draft.subject or "(No Subject)"
body = draft.body_text or ""
html_body = draft.body_html
result = await self.send_email(
to=to or None,
subject=subject,
body=body,
cc=cc or None,
bcc=bcc or None,
html_body=html_body,
in_reply_to=draft.in_reply_to,
references=draft.references or None,
)
if not result.success:
return result
try:
client = self._get_imap_client()
client.select_folder(draft_mailbox)
client.delete_messages([int(email_id)])
client.expunge()
except Exception:
pass
return result
async def reply_email(
self,
mailbox: str,
@@ -695,7 +744,6 @@ class EmailService:
reply_all: bool = False,
cc: Optional[list[str]] = None,
bcc: Optional[list[str]] = None,
reply_to: Optional[str] = None,
html_body: Optional[str] = None,
sender_email: Optional[str] = None,
sender_name: Optional[str] = None,
@@ -703,12 +751,11 @@ class EmailService:
return await self.send_email(
body=body,
bcc=bcc,
reply_to=reply_to,
html_body=html_body,
sender_email=sender_email,
sender_name=sender_name,
reply_to_email_id=email_id,
reply_mailbox=mailbox,
in_reply_to_email_id=email_id,
in_reply_to_mailbox=mailbox,
reply_all=reply_all,
cc=cc,
)
@@ -844,7 +891,6 @@ class EmailService:
body: str,
cc: Optional[list[str]] = None,
bcc: Optional[list[str]] = None,
reply_to: Optional[str] = None,
html_body: Optional[str] = None,
in_reply_to: Optional[str] = None,
references: Optional[list[str]] = None,
@@ -862,8 +908,6 @@ class EmailService:
msg["Cc"] = ", ".join(cc)
if bcc:
msg["Bcc"] = ", ".join(bcc)
if reply_to:
msg["Reply-To"] = reply_to
if in_reply_to:
msg["In-Reply-To"] = in_reply_to
if references: