from __future__ import annotations from typing import Any _POLL_EMOJI_MAP = { "A": ("1️⃣", "one"), "B": ("2️⃣", "two"), "C": ("3️⃣", "three"), "D": ("4️⃣", "four"), "E": ("5️⃣", "five"), } YES_NO_EMOJIS = [("✅", "yes"), ("❌", "no")] def build_poll_props( question: str, options: list[str], poll_id: str = "", ) -> dict[str, Any]: """构建 Mattermost poll attachments props。""" if len(options) < 2: options = list(options) + ["—"] action_options = [] for i, opt in enumerate(options[:5]): key_letter = chr(65 + i) emoji, label = _POLL_EMOJI_MAP.get(key_letter, ("❓", f"option_{i}")) action_options.append( { "text": f"{emoji} {opt}", "value": f"poll_{poll_id}_opt_{key_letter}", } ) attachment = { "fallback": f"Poll: {question}", "title": f"📊 {question}", "text": "\n".join( f"{_POLL_EMOJI_MAP.get(chr(65 + i), ('❓', ''))[0]} {opt}" for i, opt in enumerate(options[:5]) ), "actions": [ { "name": f"poll_{poll_id}", "integration": { "url": "", # 由回调端点填充 "context": { "action": "poll_vote", "poll_id": poll_id, }, }, "type": "select", "options": action_options, }, ], } return { "attachments": [attachment], "props": {"poll_id": poll_id, "type": "poll"}, } def build_yes_no_poll_props(question: str, poll_id: str = "") -> dict[str, Any]: """构建是/否投票。""" attachment = { "fallback": f"Poll: {question}", "title": f"📊 {question}", "text": "选择你的答案:", "actions": [ { "name": f"poll_{poll_id}_yes", "integration": { "url": "", # 由回调端点填充 "context": { "action": "poll_vote", "poll_id": poll_id, "vote": "yes", }, }, "type": "button", "text": "✅ 是", "value": "yes", }, { "name": f"poll_{poll_id}_no", "integration": { "url": "", # 由回调端点填充 "context": {"action": "poll_vote", "poll_id": poll_id, "vote": "no"}, }, "type": "button", "text": "❌ 否", "value": "no", }, ], } return { "attachments": [attachment], "props": {"poll_id": poll_id, "type": "yes_no_poll"}, } def parse_poll_action(context: dict) -> dict: """解析 poll action context。""" return { "action": context.get("action", ""), "poll_id": context.get("poll_id", ""), "vote": context.get("vote", ""), }