How authentication works while reading outlook emails with python and win32com - python

I understood that we can read emails from outlook using the following code(Reading e-mails from Outlook with Python through MAPI).
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.GetLast()
body_content = message.body
print body_content
But we are not providing username and password anywhere in the above code.
Then How did the code authenticate the outlook account.
Can any one explain how the authentication is happening here.

win32com.client is interacting with Outlook COM object. Since Outlook is a singleton, you are actually spawning a "hidden" instance of Outlook. Remember that every time that you log in to Outlook you don't need to put username and password. This is why Username and Password are not required here as well.
Moreover, as long as the COM object of Outlook is opened, you won't be able to open Outlook through "exlporer". This is because only one instance of Outlook is allowed. You might notice that although you never opened Outlook's GUI, you still receiving the pop-up messages of new email.

Related

Sending emails with outlook using Python and HTML

How do I successfully use a sender account with a password that is not already signed in to on the Outlook application on my laptop? I want to send a message from the example account, "from#outlook.com" but it has a password. I have this password. Am I able to enter this into the existing code?
import win32com.client as client
import datetime,time
outlook=client.Dispatch("Outlook.Application")
message=outlook.Createitem(0)
namespace=outlook.GetNameSpace('MAPI')
inbox=namespace.GetDefaultFolder(6)
message=inbox.items.add
message.To="to#outlook.com"
message.CC=""
message.BCC=""
From = "from#outlook.com"
#password = ""
message.Subject="Subject text here"
message.BodyFormat = 2
message.HTMLBody = "<html><h2><span style='color:red'>There is an error with the file </b></span></h2> <body>Please check your submission and try again </body></html>"
message.Save()
message.Display()
time.sleep(5)
message.Send()
Firstly, MailItem object does not expose the From property. It exposes read-only Sender / SenderEmailAddress / SenderName properties, but they obviously cannot be set. You can set the MailItem.Account property to an instance of the Account object retrieved from the Application.Session.Accounts collection, but that requires you to configure the relevant account in Outlook first.
As a general rule, Outlook wont' let you send from an arbitrary one-off account not previously configured in Outlook.

How to download Outlook attachments after receiving new mail from specified receiver in python

I created a python script for downloading outlook attachments from a specified sender. I want to download outlook attachment automatically once a new mail is received from a specified sender. For example my sender send at 10.30 Am & attachment should be download on time.(10.30/10.31). Can this be done using VBA?
Below is my mail attachment's downloading script.
from pathlib import Path
from pyexpat.errors import messages
import win32com.client
import os,sys
import time
import glob
import subprocess
import xlwings as xw
import shutil
#Check existing & create folder
output_dir=Path.cwd() / "Output"
output_dir.mkdir(parents=True,exist_ok=True)
outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
inbox = outlook.GetDefaultFolder(6)
print("Success")
inbox.Name
messages=inbox.items
ytemails=[message for message in inbox.Items if
message.SenderEmailAddress.endswith('123#gmail.com')]
i1=0
for message in ytemails:
print("insta =",message)
i1=i1+1
sender=message.Sender
subject = message.Subject
body=message.body
attachments=message.Attachments
print(str(i1))
if(str(sender).__contains__("inqube")):
print("message =",message)
#time.sleep(20)
target_folder=output_dir / str(subject)
if os.path.exists(target_folder):
print(str(target_folder))
print("Error")
elif (target_folder.exists):
print(str(target_folder))
target_folder.mkdir(parents=True, exist_ok=True)
print("step >> "+str(i1))
for attachment in attachments:
print(str(attachment))
attachment.SaveAsFile(target_folder / str(attachment))
Thanks.
You need to handle the NewMailEx event of the Application class if you need to handle incoming emails instantly. This event fires once for every received item that is processed by Microsoft Outlook. The item can be one of several different item types, for example, MailItem, MeetingItem, or SharingItem. The NewMailEx event fires when a new message arrives in the Inbox and before client rule processing occurs. Use the Entry ID represented by the EntryIDCollection string to call the NameSpace.GetItemFromID method and process the item.
Also you may hook the ItemAdd event of the Items class for the Inbox folder. Both approaches have its pros and cons.
But never iterate over all items in the folder:
ytemails=[message for message in inbox.Items if
message.SenderEmailAddress.endswith('123#gmail.com')]
Instead, you need to use the Find/FindNext or Restrict methods of the Items class. These methods allow getting items that correspond to your conditions without iterating over all items in the folder. Read more about these methods in the following articles:
How To: Use Restrict method to retrieve Outlook mail items from a folder
How To: Use Find and FindNext methods to retrieve Outlook mail items from a folder (C#, VB.NET)

Outlook Check Message Type

I’m using a python package called win32com to directly access and scrape the inboxes from Outlook. As the Outlook application is setup to have multiple email accounts, I’ve had to adapt my code to read messages from multiple email accounts. However, the messages contains calendar invites and I just want email messages to be scraped. Is there a way to filter the messages based on type?
Outlook = client.Dispatch(“Outlook.Application”).GetNameSpace(“MAPI”)
Messages = outlook.Folders(“test#test.com).Folders(“Inbox”)
For msg in messages:
#Do Something
Yes, you need to check if the object is of type OlObjectClass.olMail, which is represented by value 43. You can check all enumerations here.
Outlook = client.Dispatch(“Outlook.Application”).GetNameSpace(“MAPI”)
Messages = outlook.Folders(“test#test.com).Folders(“Inbox”)
for msg in messages:
if msg.Class == 43: # OlObjectClass.olMail
#Do Something

win32com Python: Connecting to one of multiple mailboxes

I have 2 mailboxes (abc#er.com and def#er.com) in outlook and need to connect to a specific mailbox. By default, Python's win32com.client is connecting to the wrong one.
Is there a parameter to specify which mailbox to connect to? My code is:
outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
inbox = outlook.GetDefaultFolder(6)
messages = inbox.Items
I have tried very hard to find which parameters allow me to connect to a specific mailbox but did not see anything. Thanks for your help.
You should be able to enumerate the mailboxes with:
for folder in outlook.Folders:
print(folder.Name)

How to access latest mail from a specific sender in outlook using python script

Using the following code, I am able to access the latest mail from outlook. But I want to access the latest mail from a particular sender.
import win32com.client
win32com
inbox = outlook.GetDefaultFolder(6) # "6" refers to the index of a folder - in this case,
# the inbox. messages = inbox.Items
message = messages.GetLast()
body_content = message.body
print body_content
I have seen the following code to get the sender's address. But I am unable to get the latest mail from that address using Getlast()
for m in messages:
if m.SenderEmailAddress == 'some_sender#somewhere.com':
print(m)
The items in a folder are not stored in any particular order until you call Items.Sort.
Sort the items by the ReceivedTime property, then use Items.Find to search on the SenderEmailAddress property.
I tried a lot and ended up with this.It won't able to use the sender address instead it uses the sender name.
for m in messages:
if m.SenderName == 'some_sender_name':
print(m)

Categories

Resources