Skip to content

Instantly share code, notes, and snippets.

@mvelazc0
Last active April 9, 2024 20:33
Show Gist options
  • Save mvelazc0/9d6ec23139cd10c9481d356e01e660dc to your computer and use it in GitHub Desktop.
Save mvelazc0/9d6ec23139cd10c9481d356e01e660dc to your computer and use it in GitHub Desktop.
Read M365 emails using the Exchange Web Services API
import requests
from xml.etree import ElementTree as ET
# https://github.com/3gstudent/Homework-of-Python/blob/master/ewsManage.py
# Authentication details
client_id = ''
client_secret = ''
tenant_id = ''
mailbox = '[email protected]'
# Acquire token (similar to the PowerShell script)
# Token request endpoint
token_url = f'https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token'
# Token request payload
data = {
'grant_type': 'client_credentials',
'client_id': client_id,
'client_secret': client_secret,
'scope': 'https://outlook.office365.com/.default'
}
# Requesting the token
response = requests.post(token_url, data=data)
access_token = response.json().get('access_token')
# Function to create SOAP request for FindItem
def create_find_item_soap_request(mailbox):
return f"""
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
<soap:Header>
<t:RequestServerVersion Version="Exchange2013"/>
<t:ExchangeImpersonation>
<t:ConnectingSID>
<t:PrimarySmtpAddress>{mailbox}</t:PrimarySmtpAddress>
</t:ConnectingSID>
</t:ExchangeImpersonation>
</soap:Header>
<soap:Body>
<FindItem xmlns="http://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types"
Traversal="Shallow">
<ItemShape>
<t:BaseShape>IdOnly</t:BaseShape>
</ItemShape>
<ParentFolderIds>
<t:DistinguishedFolderId Id="inbox"/>
</ParentFolderIds>
</FindItem>
</soap:Body>
</soap:Envelope>
"""
# Function to create SOAP request for getting emails
def create_get_item_soap_request(item_id, mailbox):
return f"""
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
<soap:Header>
<t:RequestServerVersion Version="Exchange2013"/>
<t:ExchangeImpersonation>
<t:ConnectingSID>
<t:PrimarySmtpAddress>{mailbox}</t:PrimarySmtpAddress>
</t:ConnectingSID>
</t:ExchangeImpersonation>
</soap:Header>
<soap:Body>
<GetItem xmlns="http://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
<ItemShape>
<t:BaseShape>Default</t:BaseShape>
<t:BodyType>Text</t:BodyType>
</ItemShape>
<ItemIds>
<t:ItemId Id="{item_id}"/>
</ItemIds>
</GetItem>
</soap:Body>
</soap:Envelope>
"""
# EWS URL
ews_url = "https://outlook.office365.com/EWS/Exchange.asmx"
# Headers
headers = {
"Authorization": f"Bearer {access_token}",
"Content-Type": "text/xml; charset=utf-8"
}
# Step 1: FindItem request to get email IDs
find_item_request = create_find_item_soap_request(mailbox)
find_item_response = requests.post(ews_url, headers=headers, data=find_item_request)
find_item_root = ET.fromstring(find_item_response.content)
# Extract ItemIds from FindItem response (update based on actual XML structure)
item_ids = []
for elem in find_item_root.findall('.//{http://schemas.microsoft.com/exchange/services/2006/types}ItemId'):
item_ids.append(elem.attrib['Id'])
# Step 2: GetItem requests to read emails
for item_id in item_ids:
get_item_request = create_get_item_soap_request(item_id, mailbox)
get_item_response = requests.post(ews_url, headers=headers, data=get_item_request)
get_item_root = ET.fromstring(get_item_response.content)
# Extract email details from GetItem response (update based on actual XML structure)
for message in get_item_root.findall('.//{http://schemas.microsoft.com/exchange/services/2006/types}Message'):
subject = message.find('{http://schemas.microsoft.com/exchange/services/2006/types}Subject').text
body = message.find('{http://schemas.microsoft.com/exchange/services/2006/types}Body').text
print(f"Subject: {subject}\nBody: {body}\n")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment