2626
2727Channel : TypeAlias = Optional [str ]
2828ONE_SECOND = 1
29- # Teams webhook payload size limit in bytes. The actual limit is 28KB for
30- # Adaptive Cards, but we use a slightly lower threshold to leave room for
31- # the envelope (message wrapper, attachment metadata, etc.).
3229TEAMS_PAYLOAD_SIZE_LIMIT = 27 * 1024
3330
3431
@@ -65,8 +62,6 @@ def _truncation_notice_item() -> Dict[str, Any]:
6562
6663
6764def _minimal_card (card : dict ) -> dict :
68- """Return a minimal card with just a truncation notice when even a single
69- body item is too large."""
7065 return {
7166 ** card ,
7267 "body" : [
@@ -82,9 +77,6 @@ def _minimal_card(card: dict) -> dict:
8277
8378
8479def _truncate_card (card : dict ) -> dict :
85- """Progressively remove body items from the card until the payload fits
86- within the Teams size limit. A truncation notice is appended so the
87- recipient knows content was removed."""
8880 body : List [Dict [str , Any ]] = list (card .get ("body" , []))
8981 if not body :
9082 return card
@@ -93,20 +85,16 @@ def _truncate_card(card: dict) -> dict:
9385 payload = _build_payload ({** card , "body" : body + [_truncation_notice_item ()]})
9486 if len (json .dumps (payload )) <= TEAMS_PAYLOAD_SIZE_LIMIT :
9587 break
96- body .pop () # remove the last body item
88+ body .pop ()
9789
9890 truncated = {** card , "body" : body + [_truncation_notice_item ()]}
99- # If even a single body item plus the notice is too large, fall back to
100- # a minimal card.
10191 if len (json .dumps (_build_payload (truncated ))) > TEAMS_PAYLOAD_SIZE_LIMIT :
10292 return _minimal_card (card )
10393 return truncated
10494
10595
10696def send_adaptive_card (webhook_url : str , card : dict ) -> requests .Response :
10797 payload = _build_payload (card )
108-
109- # Proactively truncate if the payload exceeds the Teams size limit.
11098 payload_json = json .dumps (payload )
11199 if len (payload_json ) > TEAMS_PAYLOAD_SIZE_LIMIT :
112100 logger .warning (
0 commit comments