diff --git a/modules/connectors/providerMsft/connectorMsft.py b/modules/connectors/providerMsft/connectorMsft.py index 49f6fdaa..52e50af2 100644 --- a/modules/connectors/providerMsft/connectorMsft.py +++ b/modules/connectors/providerMsft/connectorMsft.py @@ -62,7 +62,7 @@ async def _makeGraphCall( ) -> Dict[str, Any]: """Execute a single Microsoft Graph API call.""" url = f"{_GRAPH_BASE}/{endpoint.lstrip('/')}" - contentType = "application/json" + contentType = "application/json; charset=utf-8" if method == "PUT" and isinstance(data, bytes): contentType = "application/octet-stream" headers = { @@ -271,6 +271,17 @@ class SharepointAdapter(_GraphApiMixin, ServiceAdapter): # Outlook Adapter # --------------------------------------------------------------------------- +_CHARSET_META = '' + +def _ensureHtmlCharset(html: str) -> str: + """Ensure HTML body has a charset meta tag so Outlook renders UTF-8 correctly.""" + if "charset" in html.lower(): + return html + if html.strip().lower().startswith("", f"
{_CHARSET_META}", 1) + return f"{_CHARSET_META}{html}" + + class OutlookAdapter(_GraphApiMixin, ServiceAdapter): """ServiceAdapter for Outlook (mail, calendar) via Microsoft Graph.""" @@ -433,9 +444,12 @@ class OutlookAdapter(_GraphApiMixin, ServiceAdapter): attachments: list of {"name": str, "contentBytes": str (base64), "contentType": str} """ + content = body + if bodyType.upper() == "HTML": + content = _ensureHtmlCharset(body) message: Dict[str, Any] = { "subject": subject, - "body": {"contentType": bodyType, "content": body}, + "body": {"contentType": bodyType, "content": content}, "toRecipients": [{"emailAddress": {"address": addr}} for addr in to], } if cc: diff --git a/modules/workflows/methods/methodOutlook/actions/composeAndDraftEmailWithContext.py b/modules/workflows/methods/methodOutlook/actions/composeAndDraftEmailWithContext.py index a191e84b..22c5ff62 100644 --- a/modules/workflows/methods/methodOutlook/actions/composeAndDraftEmailWithContext.py +++ b/modules/workflows/methods/methodOutlook/actions/composeAndDraftEmailWithContext.py @@ -261,16 +261,16 @@ Return JSON: "Content-Type": "application/json" } - # Clean and format body content cleaned_body = body.strip() + _CHARSET_META = '' - # Check if body is already HTML if cleaned_body.startswith('') or cleaned_body.startswith('') or '