fix: retrieve UID after IMAP APPEND + handle uid=None mails in vanished check
This commit is contained in:
@@ -813,15 +813,33 @@ async def imap_sync_folder(
|
||||
and_(
|
||||
Mail.folder_id == folder_id,
|
||||
Mail.tenant_id == tenant_id,
|
||||
Mail.imap_uid.is_not(None),
|
||||
)
|
||||
)
|
||||
)
|
||||
).scalars().all()
|
||||
for db_mail in db_mails:
|
||||
if db_mail.imap_uid and db_mail.imap_uid not in imap_uids_set:
|
||||
logger.info("imap_sync_folder: deleting vanished mail %s (UID %s no longer on server)", db_mail.id, db_mail.imap_uid)
|
||||
await db.delete(db_mail)
|
||||
if db_mail.imap_uid:
|
||||
if db_mail.imap_uid not in imap_uids_set:
|
||||
logger.info("imap_sync_folder: deleting vanished mail %s (UID %s no longer on server)", db_mail.id, db_mail.imap_uid)
|
||||
await db.delete(db_mail)
|
||||
elif db_mail.message_id:
|
||||
# Mail has no UID — try to find it on IMAP by Message-ID
|
||||
try:
|
||||
mid_search = await client.uid_search(f'HEADER Message-ID "{db_mail.message_id}"')
|
||||
mid_raw = mid_search[1][0] if mid_search[1] and mid_search[1][0] else b''
|
||||
if isinstance(mid_raw, (bytes, bytearray)) and mid_raw:
|
||||
found_uids = mid_raw.decode().split()
|
||||
if found_uids:
|
||||
db_mail.imap_uid = found_uids[0]
|
||||
logger.info("imap_sync_folder: found UID %s for mail %s via Message-ID", found_uids[0], db_mail.id)
|
||||
else:
|
||||
logger.info("imap_sync_folder: deleting mail %s (no UID, not found on server by Message-ID)", db_mail.id)
|
||||
await db.delete(db_mail)
|
||||
else:
|
||||
logger.info("imap_sync_folder: deleting mail %s (no UID, not found on server by Message-ID)", db_mail.id)
|
||||
await db.delete(db_mail)
|
||||
except Exception as mid_exc:
|
||||
logger.warning("imap_sync_folder: Message-ID search failed for mail %s: %s", db_mail.id, mid_exc)
|
||||
await db.flush()
|
||||
except Exception as vanished_exc:
|
||||
logger.warning("imap_sync_folder: vanished-UID check failed for folder %s: %s", folder_id, vanished_exc)
|
||||
@@ -1296,15 +1314,33 @@ async def imap_sync_account(
|
||||
and_(
|
||||
Mail.folder_id == folder.id,
|
||||
Mail.tenant_id == tenant_id,
|
||||
Mail.imap_uid.is_not(None),
|
||||
)
|
||||
)
|
||||
)
|
||||
).scalars().all()
|
||||
for db_mail in db_mails:
|
||||
if db_mail.imap_uid and db_mail.imap_uid not in imap_uids_set:
|
||||
logger.info("imap_sync_account: deleting vanished mail %s (UID %s no longer on server)", db_mail.id, db_mail.imap_uid)
|
||||
await db.delete(db_mail)
|
||||
if db_mail.imap_uid:
|
||||
if db_mail.imap_uid not in imap_uids_set:
|
||||
logger.info("imap_sync_account: deleting vanished mail %s (UID %s no longer on server)", db_mail.id, db_mail.imap_uid)
|
||||
await db.delete(db_mail)
|
||||
elif db_mail.message_id:
|
||||
# Mail has no UID — try to find it on IMAP by Message-ID
|
||||
try:
|
||||
mid_search = await client.uid_search(f'HEADER Message-ID "{db_mail.message_id}"')
|
||||
mid_raw = mid_search[1][0] if mid_search[1] and mid_search[1][0] else b''
|
||||
if isinstance(mid_raw, (bytes, bytearray)) and mid_raw:
|
||||
found_uids = mid_raw.decode().split()
|
||||
if found_uids:
|
||||
db_mail.imap_uid = found_uids[0]
|
||||
logger.info("imap_sync_account: found UID %s for mail %s via Message-ID", found_uids[0], db_mail.id)
|
||||
else:
|
||||
logger.info("imap_sync_account: deleting mail %s (no UID, not found on server by Message-ID)", db_mail.id)
|
||||
await db.delete(db_mail)
|
||||
else:
|
||||
logger.info("imap_sync_account: deleting mail %s (no UID, not found on server by Message-ID)", db_mail.id)
|
||||
await db.delete(db_mail)
|
||||
except Exception as mid_exc:
|
||||
logger.warning("imap_sync_account: Message-ID search failed for mail %s: %s", db_mail.id, mid_exc)
|
||||
await db.flush()
|
||||
except Exception as vanished_exc:
|
||||
logger.warning("imap_sync_account: vanished-UID check failed for folder %s: %s", folder.imap_name, vanished_exc)
|
||||
@@ -1559,6 +1595,18 @@ async def send_mail_via_smtp(
|
||||
)
|
||||
if append_resp.result == 'OK':
|
||||
logger.info("send_mail: uploaded sent mail to IMAP folder %s", sent_folder.imap_name)
|
||||
# Retrieve the new UID for the appended mail by searching for its Message-ID
|
||||
try:
|
||||
await imap_client.select(sent_folder.imap_name)
|
||||
search_resp = await imap_client.uid_search(f'HEADER Message-ID "{msg_id}"')
|
||||
uid_raw = search_resp[1][0] if search_resp[1] and search_resp[1][0] else b''
|
||||
if isinstance(uid_raw, (bytes, bytearray)) and uid_raw:
|
||||
new_uids = uid_raw.decode().split()
|
||||
if new_uids:
|
||||
sent_mail.imap_uid = new_uids[0]
|
||||
logger.info("send_mail: set imap_uid=%s for sent mail %s", new_uids[0], sent_mail.id)
|
||||
except Exception as uid_exc:
|
||||
logger.warning("send_mail: could not retrieve UID after APPEND: %s", uid_exc)
|
||||
else:
|
||||
logger.warning("send_mail: IMAP APPEND failed for sent folder %s: %s", sent_folder.imap_name, append_resp)
|
||||
await imap_client.logout()
|
||||
|
||||
Reference in New Issue
Block a user