O365 Python — OAuth2 Email Summary to Microsoft Teams
Script pattern for reading Microsoft 365 emails via OAuth2 (O365 library) and posting a Claude-summarised digest to a Teams channel as an Adaptive Card.
Why / When to Use
- Daily email digest automation without Basic Auth (deprecated by Microsoft in 2022)
- Summarise inbox to Teams channel on a schedule
- Works with any M365 account using OAuth2 / Azure App registration
Core Concept / Commands
Install dependencies:
pip install O365 anthropic requestsAzure App registration (one-time):
- Go to
portal.azure.com → Azure Active Directory → App registrations → New registration - Copy Client ID and Tenant ID → paste into script
- Go to
Certificates & secrets → create secret→ paste into script - Go to
API permissions → Add → Microsoft Graph → Delegated:Mail.Readoffline_access
- Click Grant admin consent
Script skeleton:
from O365 import Account
credentials = ('CLIENT_ID', 'CLIENT_SECRET')
account = Account(credentials, tenant_id='TENANT_ID')
if not account.is_authenticated:
account.authenticate(scopes=['basic', 'message_all'])
mailbox = account.mailbox()
inbox = mailbox.inbox_folder()
messages = inbox.get_messages(limit=50)
# Pass messages to Claude API for summarisation
# Post result to Teams webhookSchedule with cron (Linux/Mac):
# Run every weekday at 8:00 AM
0 8 * * 1-5 /usr/bin/python3 /path/to/email_summary_teams.pySchedule with Task Scheduler (Windows):
- Open Task Scheduler → Create Basic Task → Daily at 8:00 AM
- Action:
python C:\path\to\email_summary_teams.py
Key Options / Variants
- Filter by sender, skip newsletters, group by priority — all possible via O365 query params
- Teams card can include urgent flags, bullet points per email, total count
- Token refresh is handled automatically by O365 library after first auth
Gotchas
- Basic Auth was disabled by Microsoft for M365 in 2022 — O365 library is the correct replacement
- First run requires interactive browser auth to generate OAuth token; subsequent runs use cached refresh token
offline_accessscope is required for non-interactive token refresh
Source
Conversation “Power Automate workflow URL explanation” — 2026-05-20