
How to read email from outlook in python
There are always scenarios that you may wonder how to have a program to automatically read email from outlook and do some processing based on certain criteria. The most common use case is that you want to auto process email attachments when receiving some scheduled reports. In this article, I will be explaining to you how to use python to read email from outlook and save attachment files into the specified folder.
Prerequisites:
In order to be able to access the outlook native application, we will need to make use of the pywin32 library. Make sure you have installed this library and imported into your script.
import win32com.client #other libraries to be used in this script import os from datetime import datetime, timedelta
Let’s get started!
Like communicating with other system or app, you will need to initiate a session in the first place. By calling the GetNamespace function, you can get the outlook session for the subsequent operations.
outlook = win32com.client.Dispatch('outlook.application') mapi = outlook.GetNamespace("MAPI")
if you have configured multiple accounts in your outlook, you need to pass in the account name when accessing it’s folders, we can cover this topic in another article. For this article, let assume we only have 1 account configured in outlook.
for account in mapi.Accounts: print(account.DeliveryStore.DisplayName)
To access the inbox folder, you will need to pass in the folder type – 6 in the below function. You may refer to this doc to understand the full list of folder types, such as the draft, outbox, sent, deleted items folder etc.
inbox = mapi.GetDefaultFolder(6)
What if your email is in a sub folder under your inbox? The GetDefaultFolder has the Folders attribute where you can access to the sub folder by it’s name. For instance, to access the “your_sub_folder” under the inbox folder:
inbox = mapi.GetDefaultFolder(6).Folders["your_sub_folder"]
Read email from outlook
Now you are accessible to the inbox and it’s sub folder. You can view all the messages by getting the items as per below. But you may want filter the messages by certain criteria, such as the receiving date, from, subject etc. To do that, we can apply some filter conditions to the messages.
messages = inbox.Items
Use Restrict function to filter your email message. For instance, we can filter by receiving time in past 24 hours, and email sender as “contact@codeforests.com” with subject as “Sample Report”
received_dt = datetime.now() - timedelta(days=1) received_dt = received_dt.strftime('%m/%d/%Y %H:%M %p') messages = messages.Restrict("[ReceivedTime] >= '" + received_dt + "'") messages = messages.Restrict("[SenderEmailAddress] = 'contact@codeforests.com'") messages = messages.Restrict("[Subject] = 'Sample Report'")
Save attachment files
With all the above filters, we shall only have the messages that we are interested in. Let’s loop through the message and check for the details.
#Let's assume we want to save the email attachment to the below directory outputDir = r"C:\attachment" try: for message in list(messages): try: s = message.sender for attachment in message.Attachments: attachment.SaveASFile(os.path.join(outputDir, attachment.FileName)) print(f"attachment {attachment.FileName} from {s} saved") except Exception as e: print("error when saving the attachment:" + str(e)) except Exception as e: print("error when processing emails messages:" + str(e))
There are other attributes like Body, Size, Subject, LastModificationTime etc., please check this Microsoft documentation for more details.
If the particular problem you are trying to solve is not covered in this article, you may check my another post 5 Tips For Reading Email From Outlook In Python. And you may be also interested to see how to send email from outlook in python, please check this article.
As per always, welcome any comments or questions. Follow me on twitter for more updates.
Great post
Thank you.
I am getting an error while I try using Restrict, could you help?
pywintypes.com_error: (-2147352567, ‘Exception occurred.’, (4096, ‘Microsoft Outlook’, ‘Cannot parse condition. Error at “\xa0”.’, None, 0, -2147352567), None)
Hi, thanks for reading. It seems like you have copied some special character (non-breaking space) in your code when forming the conditions, Do you mind to share some sample code here for checking?
Thank you for the fast reply.
I managed to resolve this when using Restrict without any spaces before and after the equal sign.
Do you know how can use regex to filter emails? Let us say only messages from .*@gmail.com?
hi, you can try the below and see if it works for you:
messages = messages.Restrict(“@SQL=(urn:schemas:httpmail:sender LIKE ‘%gmail.com%’)”)
The senderemail seems not working in this case.
The other way is to directly get the send address and then do a string comparison:
if message.SenderEmailType == “EX”:
sender_address = message.Sender.GetExchangeUser().PrimarySmtpAddress
else:
# email type SMTP
sender_address = message.SenderEmailAddress
if sender_address.endswith(“gmail.com”):
…
Thank you, I will try.
I wanted to avoid checking and only run a specific list.
Thank you very much for your help!
How to get latest n mails?
You can use the Sort function to sort the messages by received time in descending order.
Something like below:
filtered_messages.Sort(“[ReceivedTime]”, Descending=True)
for message in list(filtered_messages)[:n]:
print(message.Subject, message.ReceivedTime)
Thank you very much Ken. It works perfectly. You really saved my day.
You’re welcome, Anurag -:)
getting invalid character in identifier error in line
messages = messages.Restrict(“[ReceivedTime] >= ‘” + received_dt + “‘”)
^
how do i resolve?
Hi Henry,
I noticed the double quotes were converted to unicode which causes the problem. Can you try the below?
messages = messages.Restrict(“[ReceivedTime] >= ‘” + received_dt + “‘”)
Hi, I have linked my gmail account to Outlook but now I think there is the case where you said that I have to pass in the account name when accessing it’s folders. In Outlook i have the section for Outlook and below a section for my gmail-address. This is the one that I’m trying to access. Where do I have to do that?
Hi, do you want to try the below and see whether it works for you to access the different mailbox?
inbox1 = mapi.Folders(‘abc@gmail.com’).Folders(‘Inbox’)
inbox2 = mapi.Folders(‘def@xxx.com’).Folders(‘Inbox’)
Now I’m getting this error:
Traceback (most recent call last):
File “M:/Raphael/Programming/Python/TestProject/main.py”, line 12, in <module>
inbox1 = folder.Folders(‘Inbox’)
File “M:\Programme\anaconda3\envs\TestProject\lib\site-packages\win32com\client\dynamic.py”, line 197, in __call__
return self._get_good_object_(self._oleobj_.Invoke(*allArgs),self._olerepr_.defaultDispatchName,None)
pywintypes.com_error: (-2147352567, ‘Exception occurred.’, (4096, ‘Microsoft Outlook’, ‘Der versuchte Vorgang konnte nicht ausgeführt werden. Ein Objekt wurde nicht gefunden.’, None, 0, -2147221233), None)
Note:
I split the line inbox1 = mapi.Folders(‘abc@gmail.com).Folders(‘Inbox’) into two lines to see where the error is coming from
Hi, I was able to get the email messages from the inbox folder with below (although I do not have two accounts configured in outlook). Are you able to access any of your account?
messages = mapi.Folders(‘abc@gmail.com’).Folders(‘Inbox’).Items
for m in messages:
print(m)
Hello- what if I have two accounts configured in outlook?
Hi, do you want to try if the below works? If there are multiple accounts configured, you will need to specify the account id to be accessed. Each account is basically a separate folder.
messages = mapi.Folders(‘abc@gmail.com’).Folders(‘Inbox’).Items
for m in messages:
print(m)
I tried this and still “cant find object”, do you have link to the docs when reading from an outlook account? 🙂
Hi, This was a great help for me, although my requirement is not getting fulfilled by this, I need to download the attachment from outlook using just a sender and a particular date. Could you take a look at it?
import win32com.client
import os
from datetime import datetime, timedelta
Outlook = win32com.client.Dispatch(“Outlook.Application”)
mapi=Outlook.GetNamespace(“MAPI”)
Inbox = mapi.GetDefaultFolder(6)
Messages = Inbox.Items
ReceivedDate = datetime.now()
ReceivedDate = ReceivedDate.strftime(‘%m/%d/%Y’)
messages = Messages.Restrict(“[ReceivedTime] = ‘”+ReceivedDate+”‘”)
messages = Messages.Restrict(“[SenderEmailAddress]=’example@outlook.com'”)
OutputDir = r”C:\Users\usename\Desktop”
try:
for message in list(messages):
try:
s = message.sender
print(s)
for attachment in message.Attachments:
print(attachment)
attachment.SaveASFile(os.path.join(OutputDir, attachment.FileName))
print(f”attachment {actualfilenamewithextension} from {s} saved”)
except Exception as e:
print(“error when saving the attachment:” + str(e))
except Exception as e:
print(“error when processing emails messages:” + str(e))
Hi Sai,
Received date format has to be ‘%m/%d/%Y %H:%M %p’ format, and it does not accept a date without hour & minutes. So if you just want to filter the emails on a particular date, you probably have to use restrict twice, e.g.:
from datetime import datetime, timedelta
received_dt_start = datetime.datetime(2021,2,22,0,0,0)
received_dt_end = received_dt_start + timedelta(hours=24)
messages = messages.Restrict(“[ReceivedTime] >= ‘” + received_dt_start + “‘”)
messages = messages.Restrict(“[ReceivedTime] <= '" + received_dt_end + "'")
Hi Ken, thanks for your quick look into this, not sure what’s wrong I cannot still make this work.
So, I want to take the start and end dates as variables so I used this.
import win32com.client
import os
from datetime import datetime, timedelta, date
Outlook = win32com.client.Dispatch(“Outlook.Application”)
mapi=Outlook.GetNamespace(“MAPI”)
Inbox = mapi.GetDefaultFolder(6)
Messages = Inbox.Items
dt = date.today()
received_dt_start=(datetime.combine(dt, datetime.min.time()))
received_dt_end = received_dt_start + timedelta(hours=24)
print(received_dt_start)
print(received_dt_end)
messagesfilter = Messages.Restrict(“[ReceivedTime] >= ‘” + received_dt_start + “‘”)
messagesfilter = Messages.Restrict(“[ReceivedTime] <= ‘” + received_dt_end + “‘”)
messagesfilter = Messages.Restrict(“[SenderEmailAddress]=’example@outlook.com'”)
OutputDir = r”C:\Users\username\Desktop”
try:
for message in list(messagesfilter):
try:
s = message.sender
print(s)
for attachment in message.Attachments:
print(attachment)
attachment.SaveASFile(os.path.join(OutputDir, attachment.FileName))
print(f”attachment {actualfilenamewithextension} from {s} saved”)
except Exception as e:
print(“error when saving the attachment:” + str(e))
except Exception as e:
print(“error when processing emails messages:” + str(e))
Hi Sai,
Based on what you’ve posted, you will have to format your datetime object to a string when passing to the Restrict function, e.g:
Messages.Restrict(“[ReceivedTime] >= ‘” + received_dt_start.strftime(‘%m/%d/%Y %H:%M %p’) + “‘”)
Hi Ken, I’ve changed the date format to m/d/y hh: mm am but the script is not going through the try and except method loop, if it goes through satisfying the condition it should give us the sender’s name if it’s not satisfied it should at least give the final except condition “error when processing emails” but that’s not happening. I’ve looked at the loop and as per my understanding it’s correct could you please check this?
messagesfilter = Messages.Restrict(“[ReceivedTime] >= ‘” + received_dt_start.strftime(‘%m/%d/%Y %H:%M %p’) + “‘”)
messagesfilter = Messages.Restrict(“[ReceivedTime] <= ‘” + received_dt_end.strftime(‘%m/%d/%Y %H:%M %p’) + “‘”)
messagesfilter = Messages.Restrict(“[SenderEmailAddress]=’example@outlook.com'”)
OutputDir = r”C:\Users\username\Desktop”
try:
for message in list(messagesfilter):
try:
subject=message.Subject
print(subject)
sender = message.Sender
print(sender)
for attachment in message.Attachments:
print(attachment)
attachment.SaveASFile(os.path.join(OutputDir, attachment.FileName))
print(f”attachment {actualfilenamewithextension} from {s} saved”)
except Exception as e:
print(“error when saving the attachment:” + str(e))
except Exception as e:
print(“error when processing emails messages:” + str(e))
hi Sai,
Your code itself seems ok. I suggest you do step by step debugging to find out where is the issue. First try to print out email messages without using the Restrict method, then later add in the received time filter (maybe with a wider date range).
Hi Ken,
Your post helped me understand the nuances of reading mails through python.
I have been trying to read mails from a shared mail box. For some reason, the restrict date filter seems to be flip day and month. Are you aware of any reason why this might be? I input the date in the following format:
Today = Today.replace(hour =0, minute =0 ).strftime(‘%Y-%m-%d %H:%M %p’)
messages = messages.Restrict(“[ReceivedTime] >= ‘” + Today +”‘”)
and in this format as well
Today = Today.replace(hour =0, minute =0 ).strftime(‘%d-%m-%Y %H:%M %p’)
but in both cases the day and month get mixed up.
Any thoughts on this?
Hi Liz,
Based on what you’ve described, I suspect it is something to do with your PC region setting where you can specify the date and time format. e.g. if you use mm/dd/yyyy in your region setting, and when you give a date in string like ‘1-3-2021’, it be converted to a date as 3 Jan 2021 rather than 1 Mar 2021.(same happens when work with excel)
So you probably need to follow the same format as your region setting when you use strftime to convert your date to string before passing to restrict method.
Let me know if it works. 🙂
Hi Ken,
Thanks for the tip. Looks like that is the issue. The system I am using the code in has date in dd/mm/yyyy format; so I think this caused the day and month mix-up.
For the filters (ex. messages = messages.Restrict(“[Subject] = ‘Sample Report'”)) – Is there a way to use a wildcard to capture all emails that have a partial match to search term?
Hi, the Restrict method does not support wildcard matching. According to the official doc, you can use the advanced search which looks quite complicated to me.
The simply way probably would be using the below DASL query:
messages = messages.Restrict(“@SQL=(urn:schemas:httpmail:subject LIKE ‘%Sample Report%’)”)
Let me know if it works.
Hi Ken,
Your last try loop is wrong, missing file_name, indent error and try except not matching please see if i am wrong. Thanks
Thanks for your feedback. You’re correct, it was some mistake when I tried to copy the code from my source file to here. I have rectified the issues you’ve mentioned. (y)
This did work, made my life mush easier, thanks!
You are welcome. Glad to see it works.
I am stuck here
how to use messages object further to read body of email
Hi, you can loop through it and directly access the mail attributes as per below:
for message in list(messages):
print(message.Body)
You can refer to the available attributes from its official doc here.
code used to work fine but suddenly i got this error
TypeError: ‘Accounts’ object is not iterable
Not too sure how to fix it
Are you using the original code from this tutorial? Saw a post related to this question and someone suggested to replace the Accounts to Folders, which I am not sure how it could fix this issue.
Do you want to share some of your code here if it is different from the above ?
yes dear,
i used exactly the same code that worked in the first run only. i will try to replace “accounts” with folders and check
thanks!
replacing “accounts” with folder did not help either:(
I was trying to turn off the cached mode to simulate your issue, but could not replicate the same error.
If you print(mapi.Accounts.count), will you see 0 as the output? Have you tried to run the code in someone else’s PC? from the error message itself, it seems cannot find any account/folder from your outlook app.
Thanks for your super helpful article, Ken! I am having a similar problem as maissa. Even with the following super simple code:
import win32com.client as win32
outlook = win32.Dispatch(‘Outlook.Application’).GetNamespace(“MAPI”)
accounts = outlook.Session.Accounts
for account in accounts:
pass
I get “TypeError: ‘Accounts’ object is not iterable”.
If I do:
print(accounts.count)
I get: AttributeError: ‘<win32com.gen_py.Microsoft Outlook 16.0 Object Library._Accounts instance at 0x1571797904136>’ object has no attribute ‘count’
So it seems like I’m even missing some basic functionality. Would you have any suggestions for a solution?
Hi Daan,
Your code looks fine. I tried to test it in below environment:
Python 3.7 + Outlook (version 2008) + Pywin32 (version 224 & 300)
Python 3.9 + Outlook (version 2103) + Pywin32 (version 300)
Unfortunately, I could not replicate your error. Possibly you have different version of the Outlook installed which causing this issue, do you want to try out the above mentioned version and see if it works for you?
Hi Ken, thanks for your suggestion, I managed to fix it with help from an answer on stackoverflow that I can’t seem to locate anymore, but it said to delete the folder Appdata/Temp/gen.py, which indeed resolved the issue.
Hi Daan,
Glad to hear you have found a workaround for this issue and thanks for sharing it out. I did check the gen.py from pywin32 package before I tried the different Pywin32 versions, but didnt find any clue. Let me ask maissa to try your solution also.
Hi Maissa,
Daan just shared a fix for this issue. Would you want to give a try? Please refer to the comment above.
Hi ken, looking for a scenario to restrict inbox mails with 3 different domains like @abc,@123,@xyz. can we use any filter to exclude these domains.If so, please post me the code..
Hi Rek,
I’m not sure if there is simpler syntax to achieve it, but the below should work to exclude multiple domains based on the sender emails:
messages = messages.Restrict(“@SQL=(Not(urn:schemas:httpmail:senderemail LIKE ‘%@abc%’) \
And Not(urn:schemas:httpmail:senderemail LIKE ‘%@123%’) \
And Not(urn:schemas:httpmail:senderemail LIKE ‘%@xyz%’) \
)”)
Basically just use multiple logical operators to achieve it. you can find more details from here.
Messages object has no attribute Restrict is the error I have got
I am looking for exchangelib library not win32. Can you post code for exchangelib library.
Hi rek,
The messsages object was from the below if you followed the code in this post. I was able to run the code without any issue.
messages = inbox.Items
Hello, you said that if you have configured multiple accounts in your outlook, you need to pass in the account name when accessing it’s folders, you cover this topic in another article. I have not found any article that says how to do this, and I’m really struggling trying to pull emails from a different account.
Hi Trey,
Sorry that I couldn’t come out that topic, will try to do it within these a few days. For your question, You can get access to each individual account by specifying the email address as per below:
for msg in list(mapi.Folders(“abc@company.com”).Folders(“Inbox”).Items):
print(msg.Subject)
Note that the parameter passed to the Folders can be integer index or a string (case sensitive) of the folder name.
Hi, great post!
Due to some DRM/Encryption software from my company my excel files are encrypted when saved on my computer, and when encrypted I can’t e.g. read the files via pandas.
So, is there a way to read like the bytes of the attachment and directly create a pandas dataframe from that without saving the file locally?
Something like:
This doesn’t work becasue i get an attribute error on the pd.read_excel line:
AttributeError: <unknown>.content
The attachment.content conversion to bytes work with the exchangelib library but I don’t have exchange so I can’t use that. Any ideas?
Hi Alekks,
For pywin32, unfortunately there is no such attribute called content for the attachment object, whatever attributes you can find here in VBA can be used the same way in Python. so I guess you will have to save the attachment file into a temp folder and read from there.
Hi Ken,
I am getting an email with an email attachment which finally has the csv file that I want to access and manipulate data. I can write a python code for access csv file from an email. But in this case, I am not able to do so. Looking for a solution.
Regards,
Amit
Hi Amit,
Not sure if I understood your problem, I think you will need to download the attachment file first and then use the csv library to read the data. Let me know if you are looking for something else.
Thanks Ken.
I could resolve it:
outlook = win32com.client.Dispatch(‘outlook.application’)
mapi = outlook.GetNamespace(“MAPI”)
jvk = mapi.Folders[‘xxxxxxxxxx’]
inbox = jvk.Folders[‘Inbox’]
messages = inbox.Items
messages_php = messages.Restrict(“[Subject] = ‘xxxxxxxxxxx'”)
message = messages_php.GetLast()
attachment = message.Attachments.Item(1)
attachment.SaveAsFile(‘file path xxx.msg’)
msg = extract_msg.openMsg(‘xxxr.msg’)
msg.save_attachments()
file_name = ‘Cummins_xxxxx.zip’
with ZipFile(file_name, ‘r’) as zip:
zip.extractall()
osr = zip.filelist[0].filename
php_osr_df = pd.read_csv(osr)
It is working 🙂 as of now.
Glad you’ve solved your problem.:)
Im getting an error when trying to find “Inbox”, anything you guys have had? 🙂
EDIT: The Inbox looks like its names “Inbox” but it was actually named in my countrys language “Inkorg” so watch out for that one!
Okay, great post.
I wanted to ask what should i do if i just wanted to copy content from the first mail.
Hi, sorry for the late reply. You can just use the Body attribute to get the clear-text message body. e.g.:
message = list(messages)[0]
print(message.Body)
Hi am getting an error sometimes when i access ReceivedTime. Google says its a python bug. Any ideas to solve?
https://github.com/pyinstaller/pyinstaller/issues/4463
Are you running into the same issue as the one reported under the pyinstaller? I have never encountered this issue, did you see any error message?
Someone mentioned to import the win32timezone module, have you also tried that?
I am getting error following error after mapi.GetDefaultFolder(6):
<COMObject <unknown>>
are you able to print out the folders from the mapi object?
for idx, folder in enumerate(mapi.Folders):
#index starts from 1
print(idx+1, folder)
It seems like your account is not configured properly in outlook application, can you check on that?
Pls write an article “To read Outlook email from a particular sender and write it as a table to an Excel file”.
For those mentioning multiple Outlook accounts: if by any chance those accounts all come from the same server and it a Microsoft Exchange Server (or Exchange Online), you could follow the code I have in my article here https://www.codementor.io/@anananet/how-built-a-python-script-to-read-e-mails-from-an-exchange-server-z6xwh76hr
Great post and very helpful Ken! Is there a restriction on the date range for which you can download email data? I am using the code below to try and download last 60 days worth of emails, but the output is still the last 30 days worth of emails. Please note that i have used dd/mm/yyyy settings as they are my local region settings.
Kindly help!
#set date range for email messages extraction
received_dt = datetime.now() – timedelta(days=60)
received_dt = received_dt.strftime(‘%d/%m/%Y %H:%M %p’)
messages = messages.Restrict(“[ReceivedTime] >= ‘” + received_dt + “‘”)
#set sender address
messages = messages.Restrict(“[SenderEmailAddress] = ‘abc@bbb.com'”)
#messages = messages.Restrict(“[Subject] = ‘Sample Report'”)
for message in list(messages):
try:
s = message.sender
#sub = message.subject
body = message.body
print(f”message from {s} : {body}”)
except Exception as e:
print(“error when saving the attachment:” + str(e))
Hi Abhi,
Thanks for the comments. It might not be due the date/timing issue. I was able to get the old email with your code except the filtering by SenderEmailAddress does not work for me due to this email sender type.
I don’t have a perfect solution yet, but if the sender is exchange server address, then the SenderEmailAddress won’t be a readable email address, you will need to get it in the below way:
if msg.SenderEmailType = “EX” Then
print msg.Sender.GetExchangeUser().PrimarySmtpAddress
else
print msg.SenderEmailAddress
In this case, you may also try to use SenderName to filter the message.
Hy Ken
can you please tell a way where we can put credentials also and then login
Hi Shubham,
Using pywin32 lib only works when you have a local profile setup, you may want to take a look at exchangelib which works with EWS (exchange web service).
Great posts! Simply great! Using this and the “5 tips” post I’ve successfully written a program to save attachments from my outlook which has 7 other accounts linked to it.
Now it seems that Outlook must be running in order to run my program. I’d like to let the program run on a server without launching outlook. Could you please give me tips as how to access directly an exchange server to do the job? Many thanks!
Thanks for reading. Yes, the pywin32 library is relying on the outlook. If you want to run without outlook, you can take a look at exchangelib which allows you to specify the credentials for accessing your mailbox.
Hi Ken great post. Please help me with this question: how to filter unread emails?
Hi Geovanio,
You may try the below:
messages = messages.Restrict(“[UnRead] = ‘True'”)
see the documentation here
You are amazing… I had already gotten this solution. But I’m Brazilian and around here we don’t have people who lend themselves to help like you have done to everyone on this blog. Congrats
Is there anyway to add events to the outlook Calendar via python?
sorry for the late reply. Yes, it’s possible to create calendar with Pywin32 package. You can use below to create an AppointmentItem object, and then set the properties as per you wish.
appItem = outlook.CreateItem(olAppointmentItem)
Great article!
However I am finding that I can access messages.subject, messages.size, messages.ReceivedTime, messages.UnRead, but nothing much else such as messages.body, messages.SenderEmailAddress gives an error
com_error: (-2147467259, ‘Unspecified error’, None, None)
Any ideas? It is my work Outlook account, so maybe there is a block on some operations?
Hi Ian,
It supposed to be able to get all the properties stated in this VBA doc. but looks like there is some special setting done at your outlook client.
You may want to take a look at this “Modifying Outlook Users Trust settings or the registry will fix the problem“. Looks like the same issue as you encountered.
This is some great resource. Im having a little issue though.
The output is only
joe@example.com
I figured the output would be the text within the body of the email.
Im using Visual Studio Code and running debug mode.
Any help would be appreciated. Thanks!
Hi, outlook = win32com.client.Dispatch(‘outlook.application’) is for outlook apps, can I use Outlook on web?
Thanks in advance!
sorry for the late reply. It does not work for outlook web because pywin32 uses the windows COM APIs under the hood.
Do you think that this can be used to push data to outlook colander?
Yes, it’s possible to create calendar with Pywin32 package. You can use below to create an AppointmentItem object, and then set the properties as per you wish.
appItem = outlook.CreateItem(olAppointmentItem)
Novice here! can someone help me with additional codes to click on hyperlinks in the body of the email?
For folders other than Inbox, please use this.
inbox = mapi.GetDefaultFolder(6).Parent.Folders(“MyFolderName”)
how can I post single notification on teams channel when I got mail with particular subject name. the below is my code I want to run this code in background but give one notification per one mail only. if I run this code its continuously giving notification until minute end after I got mail. Please help me on this
Hi – I am getting the following error “error when getting at least one of the message attributes:(-2147352567, ‘Exception occurred.’, (4096, ‘Microsoft Outlook’, ‘The operation failed because of a registry or installation problem. Restart Outlook and try again. If the problem persists, reinstall.’, None, 0, -2147221225), None)”
I restarted the computer and outlook and still get the same error. I do get output though.
Below the relevant part of the Python code. I am getting the output but noticed the following:
1) I compared the total number of items in a terminal sub-folder to the count of outputted records in the corresponding FolderPath and they match. However, the code is always outputting the same conversation, only the attachments shown differ across records. Why aren’t the other items in the sub-folder parsed out and written to the output file? Is it possible to not repeat the same conversation in the output?
2) Sender email address field does not always show the sender’s email. Instead output looks like: /O=EXCHANGE/OU=EXCHANGE ADMINISTRATIVE GROUP (FYDIBOHF23SPDLT)/CN=RECIPIENTS/CN=Elton John:
PYTHON CODE
SenderName = message.Sender
SenderEmail = message.SenderEmailAddress
ReceivedByName = message.ReceivedByName
ReceivedOnBehalfOfName = message.ReceivedOnBehalfOfName
RecipientNames = message.To
CCNames = message.CC
BccNames = message.BCC
ConversationID = message.ConversationID
ConversationTopic = message.ConversationTopic
ReceivedTime = message.ReceivedTime
Subject = message.Subject
Body = message.Body
# count of attachment(s)
CountAttachments = message.Attachments.Count
# getting attachment(s)
try:
s = message.sender
AttachmentsFilenames = “”
for attachment in message.Attachments:
# attachment.SaveASFile(os.path.join(outputDir, attachment.FileName))
# print(f”attachment {attachment.FileName} from {s} saved”)
AttachmentsFilenames = AttachmentsFilenames + “; ” + attachment.FileName
except Exception as e:
print(“error when saving the attachment:” + str(e))
msg_elements = (folderPath, SenderName, SenderEmail, ReceivedByName, ReceivedOnBehalfOfName, RecipientNames,
CCNames, BccNames, ConversationID, ConversationTopic, ReceivedTime, Subject, Body, CountAttachments,
AttachmentsFilenames)
with open(output_file_name, ‘a’,newline=”, encoding=”utf-8″) as outcsv:
writer = csv.writer(outcsv)
writer.writerow(msg_elements)
yeah hi i have multiple accounts in my outlook would you please help me in that.
I assume that this thread is dead, but how would I go about adding a restriction to account for forwards from someone and not just direct emails?
Hi William,
there is a AutoForwarded flag which indicating whether the email is forwarded automatically from someone, not sure if that is what you want. Other than that, I don’t think there is a good way to differentiate a forwarded email and normal email in your inbox.
if forwarded email always have “FW:” in the subject, then maybe use can use wildcard matching on the email subject.
Thanks!
Hi
Great post and good explanations. May I ask you a question regarding the number of emails. So I want to read around 70,000 emails from my Inbox. Is that possible? Any limitations for the standard read you explained above? Could you please explain? Any help in this is really appreciated.
Thank you.
I have a question. What if I can using python to sign in outlook?
Hi Ken,
i have use case where mailitem.Send() is not working, instead mailitem.Display() only is working due to restriction policy in my office. do you have any alternatives for this to Send email directly instead of display?