"""Microsoft Teams Presentation Card Builder。 buildMSTeamsPresentationCard,支持 title/text/context/divider/buttons 等 通用 block 类型转换为 Adaptive Card。 """ from __future__ import annotations from typing import Any def build_presentation_card( title: str = "", blocks: list[dict[str, Any]] | None = None, ) -> dict[str, Any]: body: list[dict[str, Any]] = [] if title: body.append( { "type": "TextBlock", "size": "Large", "weight": "Bolder", "text": title, } ) for block in blocks or []: converted = _convert_block(block) if converted: if isinstance(converted, list): body.extend(converted) else: body.append(converted) return { "type": "AdaptiveCard", "version": "1.5", "body": body, } def _convert_block(block: dict[str, Any]) -> dict[str, Any] | list[dict[str, Any]] | None: block_type = block.get("type", "text") if block_type == "text": return { "type": "TextBlock", "text": block.get("text", ""), "wrap": block.get("wrap", True), "size": block.get("size", "default"), "weight": block.get("weight", "default"), "isSubtle": block.get("is_subtle", False), "spacing": block.get("spacing", "default"), } if block_type == "context": return { "type": "TextBlock", "text": block.get("text", ""), "wrap": True, "isSubtle": True, "size": "small", "spacing": "small", } if block_type == "divider": return [] if block_type == "section": items: list[dict[str, Any]] = [] title = block.get("title", "") if title: items.append( { "type": "TextBlock", "text": title, "weight": "Bolder", "wrap": True, } ) text = block.get("text", "") if text: items.append( { "type": "TextBlock", "text": text, "wrap": True, } ) return items if block_type == "facts": facts = block.get("facts", {}) return { "type": "FactSet", "facts": [{"title": k, "value": v} for k, v in facts.items()], } if block_type == "image": return { "type": "Image", "url": block.get("url", ""), "altText": block.get("alt", ""), "size": block.get("size", "auto"), } if block_type == "buttons": buttons = block.get("buttons", []) return { "type": "ActionSet", "actions": [ { "type": "Action.OpenUrl" if btn.get("url") else "Action.Submit", "title": btn.get("title", "Button"), "url": btn.get("url", ""), "data": btn.get("data", {}), "style": btn.get("style", "default"), } for btn in buttons ], } return None def add_actions_to_card( card: dict[str, Any], actions: list[dict[str, Any]], ) -> dict[str, Any]: formatted = [ { "type": "Action.OpenUrl" if a.get("url") else "Action.Submit", "title": a.get("title", "Action"), "url": a.get("url", ""), "data": a.get("data", {}), "style": a.get("style", "default"), } for a in actions ] card["actions"] = formatted return card