From c6f26ebabf2facd5679503d3caa29235ac5555a0 Mon Sep 17 00:00:00 2001 From: GuyEshdat Date: Sat, 21 Mar 2026 05:02:21 +0200 Subject: [PATCH 1/3] Revert "Merge pull request #2160 from elementary-data/devin/1773995331-truncate-teams-webhook-payload" This reverts commit ed170b7b2f25820738e2bd4a8ff98783a75144db, reversing changes made to 31e7528dd31ebee0acbfb322225bf3a84a7104c0. --- .../messaging_integrations/teams_webhook.py | 62 +------------------ 1 file changed, 3 insertions(+), 59 deletions(-) diff --git a/elementary/messages/messaging_integrations/teams_webhook.py b/elementary/messages/messaging_integrations/teams_webhook.py index 533fe82a1..6c4fa7feb 100644 --- a/elementary/messages/messaging_integrations/teams_webhook.py +++ b/elementary/messages/messaging_integrations/teams_webhook.py @@ -1,7 +1,6 @@ -import json from datetime import datetime, timezone from http import HTTPStatus -from typing import Any, Dict, List, Optional +from typing import Any, Optional import requests from ratelimit import limits, sleep_and_retry @@ -26,7 +25,6 @@ Channel: TypeAlias = Optional[str] ONE_SECOND = 1 -TEAMS_PAYLOAD_SIZE_LIMIT = 27 * 1024 class TeamsWebhookHttpError(MessagingIntegrationError): @@ -38,8 +36,8 @@ def __init__(self, response: requests.Response): ) -def _build_payload(card: dict) -> dict: - return { +def send_adaptive_card(webhook_url: str, card: dict) -> requests.Response: + payload = { "type": "message", "attachments": [ { @@ -50,60 +48,6 @@ def _build_payload(card: dict) -> dict: ], } - -def _truncation_notice_item() -> Dict[str, Any]: - return { - "type": "TextBlock", - "text": "_... Content truncated due to message size limits._", - "wrap": True, - "isSubtle": True, - } - - -def _minimal_card(card: dict) -> dict: - return { - **card, - "body": [ - { - "type": "TextBlock", - "text": "Alert content too large to display in Teams.", - "wrap": True, - "weight": "bolder", - } - ], - } - - -def _truncate_card(card: dict) -> dict: - body: List[Dict[str, Any]] = list(card.get("body", [])) - if not body: - return card - - while len(body) > 1: - payload = _build_payload({**card, "body": body + [_truncation_notice_item()]}) - if len(json.dumps(payload)) <= TEAMS_PAYLOAD_SIZE_LIMIT: - break - body.pop() - - truncated = {**card, "body": body + [_truncation_notice_item()]} - if len(json.dumps(_build_payload(truncated))) > TEAMS_PAYLOAD_SIZE_LIMIT: - return _minimal_card(card) - return truncated - - -def send_adaptive_card(webhook_url: str, card: dict) -> requests.Response: - payload = _build_payload(card) - payload_json = json.dumps(payload) - if len(payload_json) > TEAMS_PAYLOAD_SIZE_LIMIT: - logger.warning( - "Teams webhook payload size (%d bytes) exceeds limit (%d bytes), " - "truncating card body", - len(payload_json), - TEAMS_PAYLOAD_SIZE_LIMIT, - ) - card = _truncate_card(card) - payload = _build_payload(card) - response = requests.post( webhook_url, json=payload, From 520be22f2496bd18b5c6f60514444d7b9b53a0f1 Mon Sep 17 00:00:00 2001 From: GuyEshdat Date: Sat, 21 Mar 2026 22:40:12 +0200 Subject: [PATCH 2/3] rasing TeamsWebhookPayloadTooLargeError if recieved response 413 for teams, either in the status code or inside the response text --- .../messages/messaging_integrations/teams_webhook.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/elementary/messages/messaging_integrations/teams_webhook.py b/elementary/messages/messaging_integrations/teams_webhook.py index 6c4fa7feb..3df237bff 100644 --- a/elementary/messages/messaging_integrations/teams_webhook.py +++ b/elementary/messages/messaging_integrations/teams_webhook.py @@ -36,6 +36,15 @@ def __init__(self, response: requests.Response): ) +class TeamsWebhookPayloadTooLargeError(MessagingIntegrationError): + def __init__(self, response: requests.Response): + self.status_code = response.status_code + self.response = response + super().__init__( + f"Teams webhook payload size ({len(response.text)} bytes) exceeds limit" + ) + + def send_adaptive_card(webhook_url: str, card: dict) -> requests.Response: payload = { "type": "message", @@ -89,6 +98,9 @@ def send_message( if response.status_code not in (HTTPStatus.OK, HTTPStatus.ACCEPTED) or ( response.status_code == HTTPStatus.OK and len(response.text) > 1 ): + if "HTTP error 413" in response.text: + raise TeamsWebhookPayloadTooLargeError(response) + raise MessagingIntegrationError( f"Could not post message to Teams via webhook. Status code: {response.status_code}, Error: {response.text}" ) From 69e6e4d86f4676f29b773391aa5aee83c067a26a Mon Sep 17 00:00:00 2001 From: Michael Myaskovsky Date: Sun, 22 Mar 2026 10:52:49 +0200 Subject: [PATCH 3/3] fixed coderabbits comment --- .../messaging_integrations/teams_webhook.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/elementary/messages/messaging_integrations/teams_webhook.py b/elementary/messages/messaging_integrations/teams_webhook.py index 3df237bff..1be4a700c 100644 --- a/elementary/messages/messaging_integrations/teams_webhook.py +++ b/elementary/messages/messaging_integrations/teams_webhook.py @@ -1,3 +1,4 @@ +import json from datetime import datetime, timezone from http import HTTPStatus from typing import Any, Optional @@ -37,12 +38,11 @@ def __init__(self, response: requests.Response): class TeamsWebhookPayloadTooLargeError(MessagingIntegrationError): - def __init__(self, response: requests.Response): + def __init__(self, response: requests.Response, payload_size: int | None = None): self.status_code = response.status_code self.response = response - super().__init__( - f"Teams webhook payload size ({len(response.text)} bytes) exceeds limit" - ) + size_info = f" ({payload_size} bytes)" if payload_size is not None else "" + super().__init__(f"Teams webhook payload size{size_info} exceeds limit") def send_adaptive_card(webhook_url: str, card: dict) -> requests.Response: @@ -87,6 +87,7 @@ def send_message( body: MessageBody, ) -> MessageSendResult[EmptyMessageContext]: card = format_adaptive_card(body) + payload_json = json.dumps(card) try: response = send_adaptive_card(self.url, card) # For the old teams webhook version of Teams simply returning status code 200 @@ -99,7 +100,9 @@ def send_message( response.status_code == HTTPStatus.OK and len(response.text) > 1 ): if "HTTP error 413" in response.text: - raise TeamsWebhookPayloadTooLargeError(response) + raise TeamsWebhookPayloadTooLargeError( + response, payload_size=len(payload_json) + ) raise MessagingIntegrationError( f"Could not post message to Teams via webhook. Status code: {response.status_code}, Error: {response.text}"