简体   繁体   中英

Forward emails from a specifc sender in outlook via python

i try the below code but the attribute error is driving me crazy,. any thing after message, gets me an attribute error. wtv prop. i use. i end up with attribute error.

AttributeError: <unknown>.Sender

Code:

import win32com.client

outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
inbox = outlook.GetDefaultFolder(6) # "6" refers to the inbox
messages = inbox.Items

sender_email = "TDC@AE.Roco.COM"
recipient_email = "simple.invoice@net"

for message in messages:
    if message.Sender.Address == sender_email:
        new_mail = message.Forward()
        new_mail.Recipients.Add(recipient_email)
        for attachment in message.Attachments:
            new_mail.Attachments.Add(attachment)
        new_mail.Save()

Based on given answers:

import win32com.client

outlook = win32com.client.Dispatch("Outlook.Application")
mapi = outlook.GetNamespace("MAPI")
inbox = mapi.GetDefaultFolder(6)
accounts = mapi.Folders

query = '@SQL="urn:schemas:httpmail:from" = ' + "'TDC@AE.Roco.COM'" + ' AND "urn:schemas:httpmail:hasattachment" = ' + "'1'"
print(query)

try:
    items = inbox.Items.Restrict(query)
    print(f'Number of items found : {items.count}')


    def check_subfolders(folder):
        items = folder.Items.Restrict(query)
        if items.count > 0:
            print(f'{items.count} emails found in {folder.name}')
        for subfolder in folder.Folders:
            check_subfolders(subfolder)


    check_subfolders(inbox)
    for folder in mapi.Folders:
        items = folder.Items.Restrict(query)
        if items.count > 0:
            print(f'{items.count} emails found in {folder.name}')
    for item in items:
        mail = item.Forward()
        mail.Recipients.Add("simple.invoice@net")
        mail.Subject = "Fwd: " + item.Subject
        mail.Body = "Please find the forwarded message with attachments below:\n\n" + item.Body
        mail.Save()
except Exception as e:
    print(f'An error occurred: {e}')

Now I have no errors but the result returns zero, although I have mails from that specified sender!

Not all Outlook items provide the Sender property. Outlook folders may contains different kind of items - notes, calendar items, mail items, document items and etc. So, it makes sense to make sure that you deal with a mail item, for example, you could check the MessageClass property.

Instead of iterating over all items in Outlook:

for message in messages:
    if message.Sender.Address == sender_email:

Use the Find / FindNext or Restrict methods of the Items class. They allow getting items that correspond to the search criteria, so you can iterate over them without checking a property each time. Read more about these methods in the articles that I wrote for the technical blog:

Use the following search criteria to get items from the specified email address:

criteria = "@SQL=" & Chr(34) _ 
& "urn:schemas:httpmail:senderemail" & Chr(34) _ 
& " = 'eugene@astafiev.com'"

If you need to send an item from a specific sender, you can use the MailItem.SendUsingAccount property returns or sets an Account object that represents the account under which the MailItem is to be sent. Note, the other account should be configured in Outlook. For example, a sample in VBA shows how to use it:

Sub SendUsingAccount() 
 Dim oAccount As Outlook.account 
 For Each oAccount In Application.Session.Accounts 
   If oAccount.AccountType = olPop3 Then 
     Dim oMail As Outlook.MailItem 
     Set oMail = Application.CreateItem(olMailItem) 
     oMail.Subject = "Sent using POP3 Account" 
     oMail.Recipients.Add ("someone@example.com") 
     oMail.Recipients.ResolveAll 
     Set oMail.SendUsingAccount = oAccount 
     oMail.Send 
   End If 
 Next 
End Sub

Another approach is to use the MailItem.SentOnBehalfOfName property which returns or sets a string indicating the display name for the intended sender of the mail message. In that case the other user should have permissions to send on behalf of another person in Exchange.

Sender property is only exposed by the MailItem object, but you can also have ReportItem and MeetingItem objects in the Inbox folder. You need to check first that Class property == 43 (which is olMail )

Also, do not loop through all items in a folder - use Items.Find/FindNext or Items.Restrict with a query like [SenderEmailAddress] = 'TDC@AE.Roco.COM'

Quick Example

import win32com.client

def outlook_emails(Inbox):
    Filter_sender = "@SQL=""urn:schemas:httpmail:fromemail"" " \
                    "ci_phrasematch 'TDC@AE.Roco.COM'"

    items = Inbox.Items.Restrict(Filter_sender)
    print(items.Count)

    for i in reversed(range(items.Count, 0, -1)):
        if items[i].Class == 43:
            print(items[i].Subject)


if __name__ == "__main__":
    outlook = win32com.client.Dispatch(
        "outlook.Application").GetNamespace(
        "MAPI"
    )

    inbox = outlook.GetDefaultFolder(6)
    outlook_emails(inbox)

@SQL=""urn:schemas:httpmail:fromemail"" ci_phrasematch

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM