I have the following code below:
outlook = win32com.client.Dispatch('outlook.application')
mapi = outlook.GetNamespace("MAPI")
inbox = mapi.GetDefaultFolder(6).Folders["Rates"]
emails = inbox.Items
emails = emails.Restrict(f"[SenderEmailAddress] = 'louis.lai#gmail.com")
last = emails.GetLast()
print(last)
print(last.Sender)
last.ReplyAll().Display()
It's returning 'None' even though I know I have an email from them within the last hour --- double checked the email address too.
Is there something wrong with my syntax?
Should open up the email ready for me to type in my response.
Related
I have a code, which sends a new email to the chosen recipients. The email is created based on a received email, which is in the inbox.
For the email sending I use the Win32 python library.
However, since a brand new email is being created, the email from which the new email is created left 'unseen' in the inbox.
How can I set the original email to 'seen' with code?
The code is something like this:
if inbox.Items[i].UnRead == True:
outlook = win32.Dispatch('outlook.application')
mail = outlook.CreateItem(0)
mail.To = mail_list
mail.Subject = sub
mail.HTMLbody = new_body
mail.Send()
print('The email was sent successfully!')
Thank you in advance.
the email from which the new email is created left 'unseen' in the inbox.
You just need to set the MailItem.UnRead property to false on that item. The property returns or sets a boolean value that is true if the Outlook item has not been opened (read).
Try inbox.Items[i].UnRead = False after mail.Send()
Example
import win32com.client
def send_new_email(inbox):
for item in inbox.items:
if item.UnRead:
print(item.Subject)
new_email = outlook.CreateItem(0)
new_email.Display()
item.UnRead = False
if __name__ == "__main__":
outlook = win32com.client.Dispatch("outlook.Application")
olNs = outlook.GetNamespace("MAPI")
inbox = olNs.GetDefaultFolder(6)
send_new_email(inbox)
I'm having an issue like this one
outlook = win32com.client.Dispatch('outlook.application')
accounts = win32com.client.Dispatch("outlook.Application").Session.Accounts
print(accounts[1])
mail = outlook.CreateItem(0)
mail.SentOnBehalfOfName = accounts[1]
mail.SendUsingAccount = accounts[1]
mail.To = to
mail.Subject = 'Subject TEST'
mail.HTMLBody = emailBody
mail.display()
mail.Send()
if I comment mail.Send() the window that shows up will show everything correctly but if I send it, i'll get reply This message could not be sent. You do not have the permission to send the message on behalf of the specified user. which is obviously not true since if instead of sending directly and choose the exact same email from the dropdown menu in From, and then click SEND, it will send the email with no issues.
So with the help of #Eugene Astafiev and this post I fixed the issue like this:
outlook = win32com.client.Dispatch('outlook.application')
for account in outlook.Session.Accounts:
if account.DisplayName == "marhaba#vodafone.om":
print(account)
mail = outlook.CreateItem(0)
mail._oleobj_.Invoke(*(64209, 0, 8, 0, account))
mail.To = to
mail.Subject = 'Vodafone Support'
mail.HTMLBody = emailBody
#mail.display()
mail.Send()
There is no need to use these both properties at the same time in Outlook:
mail.SentOnBehalfOfName = accounts[1]
mail.SendUsingAccount = accounts[1]
The From field available in the Outlook UI corresponds to the MailItem.SendUsingAccount property which returns or sets an Account object that represents the account under which the MailItem is to be sent. This option is available when you have multiple accounts configured in Outlook.
The MailItem.SentOnBehalfOfName property returns a string, not an Account instance, where a string indicates the display name for the intended sender of the mail message. Be aware, the permission should be given to be able to send on behalf of another person in Exchange.
So, if you have got multiple accounts configured in Outlook you may go with the following line of code:
mail.SendUsingAccount = accounts[1]
I hope you are well.
I have been doing some python practice with web scraping and have come across the win32com library and have been really struggling to get the attachment from my outlook email ( it is just the one)! I have managed to view all of the emails by the following code. I was wondering if you could help me with getting the attachment file called lets say "data_bay1.xlsx" as i am stumped on the errors. I can so far get the data from the email but i cannot get the attachment xlsx file and the attachment part of the code when i try to run it gives me errors. Please see what I have done so far and I hope any of you can help. I am using anaconda and windows. Thank you in advance! Kind regards, Lily
import win32com.client
#connecting python to outlook
outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
#connecting to our inbox
inbox = outlook.GetDefaultFolder(6)
(inbox)
# here we are ensuring the indexes exist so we can grab data
outlook=win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
for i in range(50):
try:
box = outlook.GetDefaultFolder(i)
name = box.Name
print(i, name)
except:
pass
messages = inbox.items
messages = messages.GetFirst() earlier
# get the last email
#message = messages.GetLast()
(message)
#to loop through the email in the inbox
while True:
try:
print(message.subject) # get the subject of the email
# if you use messages.GetFirst() earlier
message = messages.GetNext()
# if you use messages.GetPrevious() earlier
#message = messages.GetPrevious()
except:
# if you use messages.GetFirst() earlier
message = messages.GetNext()
# if you use messages.GetPrevious() earlier
#message = messages.GetPrevious()
# get the attachment
attachments = message.Attachments# return the first item in attachments
attachment = attachments.Item(1)
# the name of attachment file
attachment_name = str(attachment).lower()
attachment.SaveASFile(path+ 'C:\Users\lily\OneDrive - Dataenv\Documents + attachment_data_bay1)
Iterating over all items in the folder is not really a good idea:
#to loop through the email in the inbox
while True:
try:
print(message.subject) # get the subject of the email
# if you use messages.GetFirst() earlier
message = messages.GetNext()
# if you use messages.GetPrevious() earlier
#message = messages.GetPrevious()
except:
# if you use messages.GetFirst() earlier
message = messages.GetNext()
# if you use messages.GetPrevious() earlier
#message = messages.GetPrevious()
Instead, you need to use the Find/FindNext or Restrict methods of the Items to find items that correspond to your conditions. Read more about these methods in the following articles:
How To: Use Find and FindNext methods to retrieve Outlook mail items from a folder (C#, VB.NET)
How To: Use Restrict method to retrieve Outlook mail items from a folder
The best you can do is filter the list down to only the items with attachments. For that use PR_HASATTACH (DASL name is http://schemas.microsoft.com/mapi/proptag/0x0E1B000B) MAPI property and then loop through the returned items and process their Attachments collection.
Intro
I'd like to create some sort of archiving script, which would collect all Outlook (unicode) emails's date, sender (name+address), recipient(s) (name(s)+address(es)), subject and put them in a CSV file.
(The extra super solution would be if it could extract the containing folders' name and possible categories as well - although it is not a must.
And as final step, I would like to make it portable, so others could use it without having Python.)
(I'm using Python 2.7 and Outlook 2013)
Code
Here's what I have so far:
import win32com.client
import sys
import unicodecsv as csv
output_file = open('./outlook_farming_001.csv','wb')
output_writer = csv.writer(output_file, delimiter = ";", encoding='latin2')
outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
inbox = outlook.GetDefaultFolder(6) # "6" refers to the index of a folder - in this case,
# the inbox.
messages = inbox.Items
for i, message in enumerate(messages): # enumerated the items
try:
sender = message.SenderName
sender_address = message.sender.address
sent_to = message.To
date = message.LastModificationTime
subject = message.subject
output_writer.writerow([
date,
sender,
sender_address,
sent_to,
subject])
except Exception as e:
()
output_file.close()
The questions:
How to make sure it extracts all the email? (When I run the script, it works, but it extracted only 1555 emails, although my Outlook Inbox sais, it contains 4785.)
How to make it work on all the Outlook folders? (It only deals with Inbox, but I would need all the other folders (sent, and other created ones))
How to get the recipients' email address? (I can only extract the screened names)
If you have any tip for any of the questions, that would be greatly appreciated.
Thanks in advance!!
For question 2:
inbox = outlook.GetDefaultFolder(6)
"6" in the code refers to Inbox.
for folder in outlook.Folders:
print(folder.Name)
use the above for loop to look for all the folders in your mailbox.
For question 3:
To get sender email ID, you can use this piece of code:
messages = inbox.Items
message = messages.GetFirst()
sender_emailid =message.SenderEmailAddress
For question 1:
I dont have an answer. Sorry
I am trying to use python to go through outlook and get all emails by a sender. I have looked but can't find out how to do this. I can get an email by subject and return the sender, but I am looking to get all senders and then return the subject? This is what I am using to get sender by subject.
import win32com.client
outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
inbox = outlook.GetDefaultFolder(6) # "6" refers to the index of a folder - in this case,
# the inbox. You can change that number to reference
# any other folder
messages = inbox.Items
message = messages("Test 08/18/14")
print(message.sender)
This returns the sender for the mail with the subject "Test 08/19/14"
I would like to go through my email and get all email subjects from a certain sender.
It looks like you're looking for the SenderEmailAddress property.
You could go through your messages for a particular sender via:
for m in messages:
if m.SenderEmailAddress == 'some_sender#somewhere.com':
print(m)