from __future__ import annotations from typing import Any def build_buttons_template( title: str, text: str, actions: list[dict], thumbnail_url: str | None = None, alt_text: str = "Buttons Template", ) -> dict: template: dict = { "type": "buttons", "title": title[:40] if title else None, "text": text[:160], "actions": actions[:4], } if thumbnail_url: template["thumbnailImageUrl"] = thumbnail_url return { "type": "template", "altText": alt_text[:400], "template": template, } def build_confirm_template( text: str, actions: list[dict], alt_text: str = "Confirm", ) -> dict: return { "type": "template", "altText": alt_text[:400], "template": { "type": "confirm", "text": text[:240], "actions": actions[:2], }, } def build_carousel_template(columns: list[dict], alt_text: str = "Carousel") -> dict: return { "type": "template", "altText": alt_text[:400], "template": { "type": "carousel", "columns": columns[:10], }, } def build_image_carousel_template(columns: list[dict], alt_text: str = "Image Carousel") -> dict: return { "type": "template", "altText": alt_text[:400], "template": { "type": "image_carousel", "columns": columns[:10], }, } def build_image_carousel_column( image_url: str, action: dict | None = None, ) -> dict: col: dict = { "imageUrl": image_url, "imageSize": "cover", } if action: col["action"] = action return col def build_product_carousel(products: list[dict], alt_text: str = "Product Carousel") -> dict: columns = [] for product in products[:10]: column = { "thumbnailImageUrl": product.get("image_url", ""), "title": product.get("title", "")[:40], "text": product.get("description", "")[:120], "actions": [ { "type": "uri", "label": product.get("action_label", "View")[:20], "uri": product.get("action_url", ""), } ], } if product.get("price"): column["defaultAction"] = { "type": "uri", "label": "View", "uri": product.get("action_url", ""), } columns.append(column) return build_carousel_template(columns, alt_text) def build_link_menu( title: str, links: list[dict], alt_text: str = "Link Menu", ) -> dict: actions = [] for link in links[:4]: actions.append( { "type": "uri", "label": link.get("label", "")[:20], "uri": link.get("uri", ""), } ) return ( { "type": "template", "altText": alt_text[:400], "template": { "type": "buttons", "title": title[:40], "text": "", "actions": actions, }, } if actions else {} ) def build_yes_no_confirm( question: str, yes_label: str = "Yes", no_label: str = "No", alt_text: str = "Confirm", ) -> dict: return build_confirm_template( text=question, actions=[ {"type": "message", "label": yes_label[:20], "text": "yes"}, {"type": "message", "label": no_label[:20], "text": "no"}, ], alt_text=alt_text, ) def build_template_message_from_payload(payload: dict[str, Any]) -> dict | None: tmpl_type = payload.get("type", "") if tmpl_type == "buttons": return build_buttons_template( title=payload.get("title", ""), text=payload.get("text", ""), actions=payload.get("actions", []), thumbnail_url=payload.get("thumbnail_url"), alt_text=payload.get("alt_text", "Buttons Template"), ) if tmpl_type == "confirm": return build_confirm_template( text=payload.get("text", ""), actions=payload.get("actions", []), alt_text=payload.get("alt_text", "Confirm"), ) if tmpl_type == "carousel": return build_carousel_template( columns=payload.get("columns", []), alt_text=payload.get("alt_text", "Carousel"), ) if tmpl_type == "image_carousel": return build_image_carousel_template( columns=payload.get("columns", []), alt_text=payload.get("alt_text", "Image Carousel"), ) if tmpl_type == "product_carousel": return build_product_carousel( products=payload.get("products", []), alt_text=payload.get("alt_text", "Product Carousel"), ) if tmpl_type == "link_menu": return build_link_menu( title=payload.get("title", ""), links=payload.get("links", []), alt_text=payload.get("alt_text", "Link Menu"), ) if tmpl_type == "yes_no": return build_yes_no_confirm( question=payload.get("question", ""), yes_label=payload.get("yes_label", "Yes"), no_label=payload.get("no_label", "No"), alt_text=payload.get("alt_text", "Confirm"), ) return None def build_datetime_picker_action( mode: str = "datetime", label: str = "Select", data: str = "", initial: str | None = None, max_value: str | None = None, min_value: str | None = None, ) -> dict: if mode not in ("date", "time", "datetime"): mode = "datetime" action: dict = { "type": "datetimepicker", "label": label[:20], "data": data[:300], "mode": mode, } if initial: action["initial"] = initial if max_value: action["max"] = max_value if min_value: action["min"] = min_value return action