How to read the email from the different account in the outlook - python

In my outlook, I have 2 accounts(account 1 and account 2). Account 1 is the default account.
I am trying to read the email from the account 2 from the python code. I tried different approach, but it did not work.
Am posting a my code where it reads from my default account. Could you please help me to read the emails from the account 2(which is not default)
from win32com.client import Dispatch
import time
import datetime
import re
outlook = Dispatch("Outlook.Application").GetNamespace("MAPI")
inbox = outlook.GetDefaultFolder("6")
all_inbox = inbox.Items
val_date = datetime.date.today()
sub_today = 'test4'
att_today = '20201018_2.xlsx'
#att_today = re.match(regex_, )
for msg in all_inbox:
if msg.Subject.find(sub_today) != -1 and msg.SentOn.date() == val_date:
break
for att in msg.Attachments:
if att.FileName == att_today:
print(att_today)
break
try:
print(att.FileName)
#att.SaveAsFile("C:/Users/Shwettha/Downloads/attachment/"+ att.FileName)
att.SaveAsFile(os.path.join("D:\Script\Monitoring",att.FileName))
print("SUCCESSFUL","Attachments Downloaded")
except:
print("ERROR","Attachment Download Failed")

Try setting your inbox like the following
outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
inbox = outlook.Folders["0m3r#Email.com"].Folders["Inbox"]
Or use GetSharedDefaultFolder method (Outlook)
import win32com.client
Outlook = win32com.client.Dispatch("Outlook.Application")
olNs = Outlook.GetNamespace("MAPI")
Recip = olNs.CreateRecipient("0m3r#Email.com")
Recip.Resolve()
shared_inbox = olNs.GetSharedDefaultFolder(Recip, "6")
for Item in shared_inbox.Items:
print(Item.Subject)

Related

How To save all the attachments from the mail in the outlook without specifying the attachment name

I am new to python. I am trying to save all the attachment from the email without specifying the attachment name from the outlook.
We need to download the attachment with the subject name.
because attachment can come in any name and also i need to download the attachment only for past 2 days.
Could anyone help me. Below is my code
from win32com.client import Dispatch
import time
import datetime
import re
outlook = Dispatch("Outlook.Application").GetNamespace("MAPI")
inbox = outlook.GetDefaultFolder("6")
all_inbox = inbox.Items
val_date = datetime.date.today()
sub_today = 'test4'
att_today = '20201018_2.xlsx'
#att_today = re.match(regex_, )
for msg in all_inbox:
if msg.Subject.find(sub_today) != -1 and msg.SentOn.date() == val_date:
break
for att in msg.Attachments:
if att.FileName == att_today:
print(att_today)
break
try:
print(att.FileName)
#att.SaveAsFile("C:/Users/Shwettha/Downloads/attachment/"+ att.FileName)
att.SaveAsFile(os.path.join("D:\Script\Monitoring",att.FileName))
print("SUCCESSFUL","Attachments Downloaded")
except:
print("ERROR","Attachment Download Failed")

Python Outlook inbox saving attachments win32com.client

I have gotten some of the features I want but need help with 2 others.
I would like to flag the message "Mark as Done" (it's one of the Flag statuses). I have not found how to do this.
If I wanted to do this same thing for 4 other emails how would I do it, with 4 other save paths?
import win32com.client
import os
Outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
inboxfolder = Outlook.GetDefaultFolder(6) # "6" refers to the index of a folder - in this case the inbox. You can change that number to reference
inbox = inboxfolder.Items
message = inbox.GetFirst()
subject = message.Subject
sender = message.SenderEmailAddress
for m in inbox:
if m.Class == 43: # this is to make sure it is an email item and not something else.
if m.SenderEmailAddress == 'John#email.com' and m.Unread == True:
path = 'C:\\User\\Path\\Data\\John'
print ('Subject as: ' and message)
for attached in message.Attachments:
attached.SaveASFile(os.path.join(path,attached.FileName)) #Saves attachment to current folder
print (attached)
message.Unread = False
print (message.FlagStatus)
message.FlagStatus = 1 # This is to "mark as Done" but it doesn't work
message = inbox.GetNext()
elif m.SenderEmailAddress == 'Jane#email.com' and m.Unread == True:
path = 'C:\\User\\Path\\Data\\Jane'
# ... How would you add 4 more?
message = inbox.GetNext()
else:
message = inbox.GetNext()
You have to save it message.Save(), Example
import win32com.client
Outlook = win32com.client.Dispatch("Outlook.Application")
olNs = Outlook.GetNamespace("MAPI")
Inbox = olNs.GetDefaultFolder(win32com.client.constants.olFolderInbox)
for Item in Inbox.Items:
if Item.Class == 43:
Item.FlagStatus = 1
Item.Save()
For multiple emails & path use dictionary, Example
emails_with_path = {
"email#one.com": "path_one",
"email#two.com": "path_two",
"email#three.com": "path_three"
}
for m in inbox:
if m.Class == 43:
for email, path in emails_with_path.items():
if m.SenderEmailAddress == email and m.UnRead:
print(email)
print(path)

Downloading Email Attachments from Shared Folder - Python

I have the below code to download email attachments based on date sent and email subject criteria:
from datetime import date, timedelta
import os
import win32com.client
path = os.path.expanduser("C:\\Users\\xxxx\\Documents\\Projects\\VBA Projects\\VLOOKUP Automation\\Vlookup File Location")
today = date.today()
outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
inbox = outlook.Folders("xxx").Folders.Item("Inbox")
messages = inbox.Items
subject = "xxx"
dateHigh = date.today() - timedelta(days=1)
dateLow = date.today() - timedelta(days=-1)
max = 2500
for count, message in enumerate(messages):
if count > max:
break
if subject in message.subject and message.senton.date() > dateLow and message.senton.date() < dateHigh:
attachments = message.Attachments
num_attach = len([x for x in attachments])
for x in range(1, num_attach+1):
attachment = attachments.Item(x)
attachment.SaveASFile(path + '\\' + str(attachment))
Is there any way to specify criteria for only .csv attachments to be downloaded for example?
Additionally, this code was previously being used on a public folder - those folders have now been updated to shared folders. Since the update, I have had to increase the "max" from 500 to 2500 in order to find the specified emails. Is there any way to speed this up?
Thanks
Below is a way to specify which file types you want.
Please enter the file endings in the attachments_of_interest list.
from datetime import date, timedelta
import os
import win32com.client
path = os.path.expanduser("C:\\Users\\xxxx\\Documents\\Projects\\VBA Projects\\VLOOKUP Automation\\Vlookup File Location")
today = date.today()
outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
inbox = outlook.Folders("xxx").Folders.Item("Inbox")
messages = inbox.Items
subject = "xxx"
dateHigh = date.today() - timedelta(days=1)
dateLow = date.today() - timedelta(days=-1)
max_n = 2500
attachments_of_interest = ['.csv']
for count, message in enumerate(messages):
if count > max_n:
break
if subject in message.subject and message.senton.date() > dateLow and message.senton.date() < dateHigh:
attachments = message.Attachments
num_attach = len([x for x in attachments])
for x in range(1, num_attach+1):
attachment = attachments.Item(x)
attachment_fname = str(attachment)
file_ending = attachment_fname.split('.')[-1]
if not attachments_of_interest or file_ending in attachments_of_interest:
attachment.SaveASFile(path + '\\' + attachment_fname)
As for speeding up, you could use a pool:
from multiprocessing.pool import ThreadPool as Pool
from datetime import date, timedelta
import os
import win32com.client
path = os.path.expanduser("C:\\Users\\xxxx\\Documents\\Projects\\VBA Projects\\VLOOKUP Automation\\Vlookup File Location")
today = date.today()
outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
inbox = outlook.Folders("xxx").Folders.Item("Inbox")
messages = inbox.Items
subject = "xxx"
max_n = 2500
attachments_of_interest = ['.csv']
pool_size = 5
# define worker function before a Pool is instantiated
def worker(message):
dateHigh = date.today() - timedelta(days=1)
dateLow = date.today() - timedelta(days=-1)
if subject in message.subject and message.senton.date() > dateLow and message.senton.date() < dateHigh:
attachments = message.Attachments
num_attach = len([x for x in attachments])
for x in range(1, num_attach+1):
attachment = attachments.Item(x)
attachment_fname = str(attachment)
file_ending = attachment_fname.split('.')[-1]
if not attachments_of_interest or file_ending in attachments_of_interest:
attachment.SaveASFile(path + '\\' + attachment_fname)
pool = Pool(pool_size)
for count, message in enumerate(messages):
if count > max_n:
break
pool.apply_async(worker, (message,))
pool.close()
pool.join()
I think this is part of requirement to download csv only.
This outlook component has some methods which you can utilize.
Instead of messages = inbox.Items
try
messages = inbox.Items.GetFirst()
and get first message then use
messages = inbox.Items.oItems.GetNext()
so in this way you always have one message in memory and you can keep looping for longer time.
Make sure you have outlook Microsoft Outlook 16.0 Object Library or higher than 10 so that this method exists. GetFirst()
c# code used by me
Outlook.MailItem oMsg = (Outlook.MailItem)oItems.GetFirst();
//Output some common properties.
Console.WriteLine(oMsg.Subject);
Console.WriteLine(oMsg.SenderName);
Console.WriteLine(oMsg.ReceivedTime);
Console.WriteLine(oMsg.Body);
//Check for attachments.
int AttachCnt = oMsg.Attachments.Count;
Console.WriteLine("Attachments: " + AttachCnt.ToString());
Outlook.MailItem oMsg1 = (Outlook.MailItem)oItems.GetNext();

Download attachment from Outlook using Python

I am trying to download attachments from Outlook using Python, as of now am able to download the attachments by subject line but in my case I want to download multiple attachments from multiple emails where subject line starts with some string, For Ex:
Subjects are: Query 123654, Query 56975, Query 5698 like this and I want to download all of them where subject name starts with "Query".
My current code is below:
from win32com.client import Dispatch
outlook = Dispatch("Outlook.Application").GetNamespace("MAPI")
inbox = outlook.GetDefaultFolder("6")
all_inbox = inbox.Items
val_date = datetime.date.today()
sub_today = 'Query 123654'
att_today = ''
for msg in all_inbox:
if msg.Subject == sub_today and msg.Senton.date() == val_date:
break
for att in msg.Attachments:
if att.FileName == att_today:
break
try:
att.SaveAsFile('C:\\Offline Feeds\\Attachments' + '\\'+ att.FileName)
messagebox.showinfo("SUCCESSFUL","Attachments Downloaded")
except:
messagebox.showerror("ERROR","Attachment Download Failed")
You could use find() to search specific data.
sub_today = 'Query'
if msg.Subject.find(sub_today) != -1 break
If subject not include “Query”, it will return “-1”.
This is the complete code:
from win32com.client import Dispatch
outlook = Dispatch("Outlook.Application").GetNamespace("MAPI")
inbox = outlook.GetDefaultFolder("6")
all_inbox = inbox.Items
val_date = datetime.date.today()
sub_today = 'Query'
att_today = ''
for msg in all_inbox:
if msg.Subject.find(sub_today) != -1 and msg.Senton.date() == val_date:
break
for att in msg.Attachments:
if att.FileName == att_today:
break
try:
att.SaveAsFile('C:\\Offline Feeds\\Attachments' + '\\'+ att.FileName)
messagebox.showinfo("SUCCESSFUL","Attachments Downloaded")
except:
messagebox.showerror("ERROR","Attachment Download Failed")
For more information, please refer to this link:
Python String find() Method

Replying To email via Outlook in Python

I am trying to reply to emails with a keyword in the subject but I need to do it all through outlook. My current code works decently but it would be better if it could reply directly instead of creating a new message.
Hopefully this is the right place to ask this :)
outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
o = win32com.client.Dispatch("Outlook.Application")
inbox = outlook.GetDefaultFolder(6)
def check_mail():
global message
messages = inbox.Items
message = messages.GetLast()
if (message.subject.find('#Bot') != -1 and message.unread and whtlist.find(message.SenderName)!= -1 ):
return 1
else:
return 0
def Read_mail():
global message
global ACTIVE
body_content = message.body
print(bcolors.WARNING+'\n______________________________________________________________________\n'+bcolors.OKGREEN)
print (body_content)
print(bcolors.WARNING+'\n______________________________________________________________________\n'+bcolors.OKGREEN)
for att in message.Attachments:
break
try:
att.SaveAsFile(os.getcwd() + '\\new.xlsx')
print(os.getcwd())
except :
print(bcolors.WARNING+'No Attachment Found'+bcolors.OKGREEN)
message.unread=False
Msg = o.CreateItem(0)
Msg.To = message.SenderEmailAddress
print(bcolors.FAIL+'Reply sent to: {}'.format(message.SenderEmailAddress+bcolors.OKGREEN))
Msg.Subject = 'Autoreply'
Msg.Body = 'I see you {}.\n\nTesting\n-Bot'.format(message.SenderName)
Msg.Send()
Do not use Items.GetLast - it is not guaranteed to return the last received email. The Items collection is not sorted in any particular way unless you explicitly call Items.Sort. In your particular case, use Items.Restrict or Items.Find/FindNext to find the message based on your criteria (unread, subject contains a particular word, etc.).
To get a reply, call MailItem.Reply instead of Application.CreateItem - it will return the new MailItem object.

Categories

Resources