function send_email_ms365_v1
Sends an email through the Microsoft 365 Graph API with support for HTML content, multiple recipients, CC/BCC, and file attachments.
/tf/active/vicechatdev/CDocs single class/utils/notifications.py
405 - 499
moderate
Purpose
This function provides a complete email sending solution using Microsoft 365's Graph API. It handles authentication token retrieval, constructs properly formatted email messages with HTML content, manages multiple recipient types (to, cc, bcc), and supports file attachments by encoding them in base64 format. The function is designed for enterprise applications that need to send emails through Microsoft 365 infrastructure with full feature support including attachments and multiple recipient types.
Source Code
def send_email_ms365(to_addresses: List[str],
subject: str,
body_html: str,
body_text: str = None,
cc_addresses: List[str] = None,
bcc_addresses: List[str] = None,
attachments: List[Dict[str, Any]] = None) -> bool:
"""
Send email through Microsoft 365 Graph API.
Args:
to_addresses: List of recipient email addresses
subject: Email subject
body_html: HTML body content
body_text: Optional plain text body
cc_addresses: Optional list of CC recipients
bcc_addresses: Optional list of BCC recipients
attachments: Optional list of attachments as dictionaries with keys:
'filename', 'content' (bytes), 'content_type'
Returns:
Boolean indicating success
"""
try:
# Get token
token = get_ms365_token()
if not token:
logger.error("Failed to get MS365 token")
return False
# Prepare headers
headers = {
'Authorization': f'Bearer {token}',
'Content-Type': 'application/json'
}
# Prepare email data
email_data = {
'message': {
'subject': subject,
'body': {
'contentType': 'HTML',
'content': body_html
},
'toRecipients': [{'emailAddress': {'address': email}} for email in to_addresses]
},
'saveToSentItems': 'true'
}
# Add CC if provided
if cc_addresses:
email_data['message']['ccRecipients'] = [
{'emailAddress': {'address': email}} for email in cc_addresses
]
# Add BCC if provided
if bcc_addresses:
email_data['message']['bccRecipients'] = [
{'emailAddress': {'address': email}} for email in bcc_addresses
]
# Add attachments if provided
if attachments:
email_data['message']['attachments'] = []
for attachment in attachments:
# Convert content to base64
content_bytes = attachment['content']
if isinstance(content_bytes, str):
content_bytes = content_bytes.encode('utf-8')
content_b64 = base64.b64encode(content_bytes).decode('utf-8')
attachment_data = {
'@odata.type': '#microsoft.graph.fileAttachment',
'name': attachment['filename'],
'contentType': attachment.get('content_type', 'application/octet-stream'),
'contentBytes': content_b64
}
email_data['message']['attachments'].append(attachment_data)
# Send email through MS Graph API
response = requests.post(
'https://graph.microsoft.com/v1.0/users/' + settings.MS365_SENDER_EMAIL + '/sendMail',
headers=headers,
json=email_data
)
if response.status_code >= 200 and response.status_code < 300:
return True
else:
logger.error(f"MS365 API error: {response.status_code}, {response.text}")
return False
except Exception as e:
logger.error(f"Error sending email through MS365: {e}")
return False
Parameters
| Name | Type | Default | Kind |
|---|---|---|---|
to_addresses |
List[str] | - | positional_or_keyword |
subject |
str | - | positional_or_keyword |
body_html |
str | - | positional_or_keyword |
body_text |
str | None | positional_or_keyword |
cc_addresses |
List[str] | None | positional_or_keyword |
bcc_addresses |
List[str] | None | positional_or_keyword |
attachments |
List[Dict[str, Any]] | None | positional_or_keyword |
Parameter Details
to_addresses: List of email addresses for primary recipients. Must be valid email address strings. At least one recipient is required for the email to be sent.
subject: The subject line of the email as a string. Can be any text content that will appear in the email subject.
body_html: The main email body content in HTML format. This is the primary content that will be displayed to recipients. HTML tags and formatting are supported.
body_text: Optional plain text version of the email body. Currently not used in the implementation but provided for potential fallback scenarios. Defaults to None.
cc_addresses: Optional list of email addresses to be copied (CC) on the email. Each address should be a valid email string. Defaults to None if no CC recipients are needed.
bcc_addresses: Optional list of email addresses to be blind copied (BCC) on the email. Recipients in this list will receive the email but their addresses won't be visible to other recipients. Defaults to None.
attachments: Optional list of dictionaries, where each dictionary represents a file attachment. Each dictionary must contain: 'filename' (str) - name of the file, 'content' (bytes or str) - file content, 'content_type' (str, optional) - MIME type (defaults to 'application/octet-stream'). Content will be automatically base64 encoded.
Return Value
Type: bool
Returns a boolean value: True if the email was successfully sent (HTTP status code 2xx from Microsoft Graph API), False if there was any error including authentication failure, API errors, or exceptions during processing. Check logs for detailed error messages when False is returned.
Dependencies
requestsmsalbase64logging
Required Imports
import requests
import base64
import logging
from typing import List, Dict, Any
Usage Example
# Basic email sending
success = send_email_ms365(
to_addresses=['recipient@example.com'],
subject='Test Email',
body_html='<h1>Hello</h1><p>This is a test email.</p>'
)
# Email with CC, BCC, and attachments
with open('report.pdf', 'rb') as f:
pdf_content = f.read()
attachments = [
{
'filename': 'report.pdf',
'content': pdf_content,
'content_type': 'application/pdf'
},
{
'filename': 'data.txt',
'content': b'Sample text content',
'content_type': 'text/plain'
}
]
success = send_email_ms365(
to_addresses=['recipient1@example.com', 'recipient2@example.com'],
subject='Monthly Report',
body_html='<p>Please find the attached report.</p>',
cc_addresses=['manager@example.com'],
bcc_addresses=['archive@example.com'],
attachments=attachments
)
if success:
print('Email sent successfully')
else:
print('Failed to send email')
Best Practices
- Ensure get_ms365_token() function is properly implemented and returns valid OAuth2 tokens before calling this function
- Always check the return value to confirm email was sent successfully before proceeding with dependent operations
- For attachments, ensure content is in bytes format or will be properly encoded; large attachments may hit API size limits (typically 4MB for Graph API)
- The body_text parameter is currently unused in the implementation; only body_html is sent to the API
- Monitor logger output for detailed error messages when emails fail to send
- Validate email addresses before passing them to the function to avoid API errors
- Be aware of Microsoft Graph API rate limits when sending bulk emails
- The function saves sent emails to the Sent Items folder by default (saveToSentItems: true)
- Attachment content_type defaults to 'application/octet-stream' if not specified; provide specific MIME types for better email client handling
- Handle exceptions appropriately as the function catches all exceptions and returns False, masking specific error types
Tags
Similar Components
AI-powered semantic similarity - components with related functionality:
-
function send_email_ms365 99.1% similar
-
function send_email 77.7% similar
-
function gen_send_email 75.1% similar
-
function send_email_smtp 72.6% similar
-
function download_attachments_for_message 61.0% similar