I am trying to write a script in Python that will pull the contact information from the Outlook Global Address List. For each entry, I've managed to get the name of the contact, as well as the alias (with some additional parsing).
My code is posted below:
import win32com.client
o = win32com.client.gencache.EnsureDispatch("Outlook.Application")
ns = o.GetNamespace("MAPI")
adrLi = ns.AddressLists.Item("Global Address List")
contacts = adrLi.AddressEntries
numEntries = adrLi.AddressEntries.Count
nameAliasDict = {}
for i in contacts:
name = i.Name
alias = i.Address.split("=")[-1]
nameAliasDict[alias] = name
print "\nThe global address list contains",numEntries,"entries."
Is there a way I can get the full set of information that shows up when I open the GAL in Outlook (such as Title, Email Address)?
Thanks.
Use AddressEntry.GetExchangeUser to retrieve the ExchangeUser object.
If some MAPI property is not explicitly exposed by the ExchangeUser object, you can retrieve it using AddressEnttry.PropertyAccessor.GetProperty. Take a look at the GAL address entries with OutlookSpy (I am its author) - click IAddrBook | Open Root Container or IMAPISession | QueryIdentity to see GAL objects and their MAPI properties.
Related
I'm trying to search "All Outlook Items" and then find emails based on the subject list I input into the code. Once the email is found, it is moved to another folder and marked as "Task Complete" (The green check in the emails).
However, I'm having a couple of errors when trying to run the code. If anyone can guide me it'd be amazing.
Here's the code:
import win32com.client
Email = 'johndoe#gmail.com'
subjects = input("Enter a list of subjects separated by commas: ").split(",")
MoveToFolder = "folder1"
Iter_Folder = "folder2"
def find_and_download_case_number_related_emails():
Outlook = win32com.client.Dispatch("Outlook.Application")
Outlook_Location = Outlook.GetNamespace("MAPI")
Lookin_Folder = Outlook_Location.Folders[Email].Folders[Iter_Folder]
Out_MoveToFolder = Outlook_Location.Folders[Email].Folders[MoveToFolder]
for message in Lookin_Folder:
if message.TaskCompleted:
continue
for message in Lookin_Folder:
if message.Subject in subjects:
message.Move(Out_MoveToFolder)
for message in Out_MoveToFolder:
message.MarkAsTaskCompleted()
if __name__ == "__main__":
find_and_download_case_number_related_emails()
and here's the error I'm getting at the moment:
raise AttributeError("%s.%s" % (self._username_, attr))
AttributeError: <unknown>.Items. Did you mean: 'Item'?
The following line of code contains a wrong property call:
outlook.Folders.Items.Restrict
The Folders class doesn't provide the Items property. You need to get a Folder instance and only then use Items property.
I'd suggest using the NameSpace.GetDefaultFolder method which returns a Folder object that represents the default folder of the requested type for the current profile; for example, obtains the default Inbox folder for the user who is currently logged on.
To understand how the Restrict or Find/FindNext methods work in Outlook you may take a look at the following articles that I wrote for the technical blog:
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
I have prepared code for mail automation. It will read the contents of of a CSV file and compare it with mail body and fetch the information and share it via mail.
The if-statement will not work code run: it only executes the else statement.
The if-statement works only if we remove the else.
import csv
from ast import Break, If
import win32com.client as client
outlook = client.Dispatch("Outlook.Application").GetNamespace("MAPI")
folder = outlook.Folders.Item("xyx.comt")
Verizon = folder.Folders.Item("Inbox").Folders("Ver")
Inbox =folder.Folders.Item("Inbox")
message = Ver.Items
message = message.GetLast()
csv_file=csv.reader(open("C:\\Users\\Documents\\Ver2022.csv",'r'))
if message.SenderName == 'abc.com' and "INCIDENT" in message.Subject:
#Compare mail body and cvc file
messageBody=str(message.body)
for row in csv_file:
if row[2] in messageBody:
print(row)
#Extrcat data from cvc file and send to mail
NewMsg=message.Forward()
NewMsg.Subject=f"Ver||{row[1:3],row[5:7]}"
NewMsg.Body = f"Hello Team,\n\tPlease find below device deatils:\n\t Site ID :{row[1]}\n\t Device Name: {row[2]}\n\t Circuit ID :{row[3]}\n\t Circuit Type : {row[4]}\n\t Topology: {row[5]}\n\t Site Country: {row[6]}\n\t Site City: {row[7]}\n\t Site Contact details:{row[8]}\n\t Site Address :{row[9]}\n\t\n\nThanks&Regards\nabc"+NewMsg.Body
NewMsg.To=('xyz.com')
NewMsg.Send()
break
else:
NewMsg=message.Forward()
NewMsg.Subject=f"The device is not available in inventory"
NewMsg.Body = f"Hello Team,\n\tThe device is not available in inventory \n\t\nThanks&Regards\nxyz"+NewMsg.Body
NewMsg.To=('abc.com')
NewMsg.Send()
break
message.Move(Inbox)
It is not clear what values are used in the following condition:
if row[2] in messageBody:
Be aware, you may use the HTMLBody property which returns an HTML markup which represents the message body or use the Word object model. The WordEditor of the Inspector class returns a Document instance which represents your item's message body, so you can use Word properties and methods.
The Outlook object model supports three main ways of dealing/customizing the message body:
The Body property returns or sets a string representing the clear-text body of the Outlook item.
The HTMLBody property of the MailItem class returns or sets a string representing the HTML body of the specified item. Setting the HTMLBody property will always update the Body property immediately. For example:
Sub CreateHTMLMail()
'Creates a new e-mail item and modifies its properties.
Dim objMail As Outlook.MailItem
'Create e-mail item
Set objMail = Application.CreateItem(olMailItem)
With objMail
'Set body format to HTML
.BodyFormat = olFormatHTML
.HTMLBody = "<HTML><BODY>Enter the message text here. </BODY></HTML>"
.Display
End With
End Sub
The Word object model can be used for dealing with message bodies. See Chapter 17: Working with Item Bodies for more information.
My objective is to parse email body from outlook and store it in pandas dataframe thenusing regex get specific values from that dataframe and insert it using oracle database. i am done with regex and oracle script but not able to add outlook emails as dataframe. Can anyone please correct me ? Below is the script
import win32com.client
import pandas as pd
from bs4 import BeautifulSoup
from pprint import pprint
from datetime import datetime, timedelta
outlook = win32com.client.gencache.EnsureDispatch("Outlook.Application")
mapi = outlook.GetNamespace("MAPI")
inbox = mapi.Folders['rahul.vaidya#xyz.com'].Folders['Inbox'].Folders['Important']
Mail_Messages = inbox.Items
Mail_Messages = Mail_Messages.Restrict("[Subject] = 'SGPSBSH Index Level*'")
received_dt = datetime.now() - timedelta(days=1)
for mail in Mail_Messages:
receivedtime = mail.ReceivedTime.strftime('%Y-%m-%d %H:%M:%S')
body = mail.HTMLBody
html_body = BeautifulSoup(body, "lxml")
print(Mail_Messages.body)
SAMPLE EMAIL
First of all, I've noticed the following line of code:
inbox = mapi.Folders['rahul.vaidya#xyz.com'].Folders['Inbox'].Folders['Important']
Use the NameSpace.GetDefaultFolder method which returns a Folder object that represents the default folder of the requested type for the current profile; for example, obtains the default Inbox folder for the user who is currently logged on.
If you need to get the Inbox folder for a specific store in Outlook you may consider using the Store.GetDefaultFolder method instead. This method is similar to the GetDefaultFolder method of the NameSpace object. The difference is that this method gets the default folder on the delivery store that is associated with the account, whereas NameSpace.GetDefaultFolder returns the default folder on the default store for the current profile.
The Outlook object model supports three main ways of dealing with the message bodies:
The Body property returns or sets a string representing the clear-text body of the Outlook item.
The HTMLBody property of the MailItem class returns or sets a string representing the HTML body of the specified item. Setting the HTMLBody property will always update the Body property immediately. For example:
Sub CreateHTMLMail()
'Creates a new e-mail item and modifies its properties.
Dim objMail As Outlook.MailItem
'Create e-mail item
Set objMail = Application.CreateItem(olMailItem)
With objMail
'Set body format to HTML
.BodyFormat = olFormatHTML
.HTMLBody = "<HTML><BODY>Enter the message text here. </BODY></HTML>"
.Display
End With
End Sub
The Word object model can be used for dealing with message bodies. See Chapter 17: Working with Item Bodies for more information.
It is up to you which way is to choose.
I found ways to check with python using library win32com for outlook the following attributes for any given email.
#imports:
import time
from time import strftime
import pandas as pd, win32com.client as client
from win32.com.client import Dispatch
#importing the excel file that contains email addresses and corresponding flags:
df_excel = pd.read_excel(r'\\user\...\addresses.xlsx')
#adding both columns as lists:
df_excel_mail = df_excel['mail'].tolist();df_excel_flag = df_excel['flag'].tolist()
outlook = client.Dispatch('Outlook.Application').GetNamespace('MAPI')
main_account = outlook.Folders.Item(1)
folder_inbox = main_account.Folders['Inbox'].Folders['Test']
folder_inbox_WIP = main_account.Folders['Inbox'].Folders['Test'].Folders['WIP']
while True:
time.sleep(0)
messages = folder_inbox.Items.Count
if messages > 0:
for i in reversed(range(0,messages)):
message = folder_inbox.Item[i]
for y, z, in zip(df_excel_mail,df_excel_flag)
if message.Categories == '' and y == message.SenderEmailAddress and z != 'nan'
message.Categories = z
message.Save
message.Move(folder_inbox_WIP)
messages_v2 = folder_inbox_WIP.Items.Count
if folder_inbox_WIP .Items.Count > 0:
for ii in reversed (range(0,messages_v2)):
message_v2 = folder_inbox_WIP[ii]
message_v2.Move(folder_inbox)
if strftime('%H, %M, %N') >= strftime('18:00:00')
break
I would like to access for any given email:
receiver list (how would that work if I have more than one)?
cc list (" ")
Is there any other way to update the category on an email other than moving this email from a folder to another? I am working on a batch process and this moving in/out is slowing things.
When the email is sent from an email address "on behalf" of another email address how can I access the email on behalf?
Use MailItem.Recipients collection.
See #1 and check for each recipient's Recipient.Type property equal olCC ( =2)
Of course - set the MailItem.Categpries property. Don't forget to call MailItem.Save
Use the MailItem.SenderEmailAddress. For the sent on behalf of address, read the PR_SENT_REPRESENTING_EMAIL_ADDRESS MAPI property. Access it using MailItem.PropertyAccessor.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x0065001F")
In general, take a look at various Outlook object using OutlookSpy (I am its author) to familiarize yourself with the Outlook Object Model.
Also keep in mind that to access a subfolder of the Inbox folder, it is better to use something like
out_iter_folder = outlook.GetDefaultFolder(6).Folders['TEST']
where 6 is olFolderInbox constant.
Is there a Python function for changing the subject line of an Outlook mail item?
I have seen solutions for this using VBA. Was looking for a function/ method in python.
Thanks
Update:
Here's what i am trying :
import win32com.client as win32
outlook = win32.gencache.EnsureDispatch('Outlook.Application')
mapi = outlook.GetNamespace('MAPI')
folder = mapi.GetDefaultFolder(6)
messages = folder.Items
# Change the current subject line to 'Testing subject change'
messages.GetFirst().Subject = 'Testing subject change'
However, the subject line doesn't change. Is there any specific function i should be using?
This short piece of code will replace all Subject lines of all emails in the specified folder, in this case "Drafts" (provided your Office is in English)
import win32com.client as win32
outlook = win32.Dispatch("Outlook.Application").GetNamespace("MAPI")
acc = outlook.Folders("myaddress#provider.com")
eMailFolder = acc.folders("Drafts") #This is the localized name of your folder, as it appears in Outlook's GUI
def replaceSubjectLine(email:object):
print(email.Subject)
email.Subject = "This is the new subject line"
email.Save
print(email.Subject)
for message in eMailFolder.Items:
replaceSubjectLine(message)
In Short: You read in the MailItem Object into Python, then changed one of its Properties (Subject), but you never .Save the changed MailItem to Outlook.