Search code examples
pythonoutlookoutlook-filter

Copy attachment from todays received email to folder with python


I have a script which copies an attachment from outlook to a folder on my laptop. So far so good, if I only have one email with the defined Subject and Attachment everything works fine. Today I realized that there's a problem when I have a newer and an older email with the same subject and attachment name in my inbox - it looks like it randomly takes the old or the new one.

Question: Is there a way to tell the script to either always take the youngest mail or take the mail received today? I tried around with GetLast() and GetFirst(), what I found in stackoverlow, but wasn't sure where to add it exactly (my trys resulted in errors). Anyone having an idea?

from win32com.client import Dispatch
import datetime as date

outlook = Dispatch("Outlook.Application").GetNamespace("MAPI")
inbox = outlook.GetDefaultFolder("6")
all_inbox = inbox.Items
val_date = date.date.today()

sub_today = 'Email Subject'
att_today = 'Attachment.zip'

for msg in all_inbox:
    if msg.Subject == sub_today:
        break

for att in msg.Attachments:
    if att.FileName == att_today:
        break


att.SaveAsFile(r'C:\path\to\my\folder\Attachment.zip')

EDIT (SOLUTION):

import win32com.client
Outlook = win32com.client.Dispatch("Outlook.Application")
olNs = Outlook.GetNamespace("MAPI")
Inbox = olNs.GetDefaultFolder("6")

Filter = ("@SQL=" + chr(34) + "urn:schemas:httpmail:subject" +
          chr(34) + " Like 'ATTACHMENTNAMEHERE' AND " +
          chr(34) + "urn:schemas:httpmail:hasattachment" +
          chr(34) + "=1")


Items = Inbox.Items.Restrict(Filter)
Items.Sort('[ReceivedTime]', False)
Item = Items.GetLast()

for attachment in Item.Attachments:
    print(attachment.FileName)
    if attachment.FileName == "ATTACHMENT.zip":
        attachment.SaveAsFile(r"C:\path\to\my\folder\Attachment.zip")

Solution

  • GetLast and GetFirst are methods linked to inbox.Items

    all_inbox = inbox.Items
    all_inbox.Sort('[ReceivedTime]', True)
    first = all_inbox.GetFirst()
    last = all_inbox.GetLast()
    

    Edit: As stated by @Dmitry Streblechenko you need to sort by ReceivedTime first the inbox.Items