from __future__ import annotations from typing import Any def build_section(text: str, *, accessory: dict | None = None) -> dict[str, Any]: block: dict[str, Any] = { "type": "section", "text": {"type": "mrkdwn", "text": text}, } if accessory: block["accessory"] = accessory return block def build_divider() -> dict[str, Any]: return {"type": "divider"} def build_button(text: str, action_id: str, *, value: str = "", style: str = "") -> dict[str, Any]: btn: dict[str, Any] = { "type": "button", "text": {"type": "plain_text", "text": text}, "action_id": action_id, } if value: btn["value"] = value if style in ("primary", "danger"): btn["style"] = style return btn def build_actions(*elements: dict[str, Any]) -> dict[str, Any]: return { "type": "actions", "elements": list(elements), } def build_approval_blocks( title: str, detail: str, confirm_action_id: str = "exec_approve", reject_action_id: str = "exec_reject", confirm_text: str = "确认执行", reject_text: str = "取消", ) -> list[dict[str, Any]]: return [ { "type": "header", "text": {"type": "plain_text", "text": title}, }, { "type": "section", "text": {"type": "mrkdwn", "text": detail}, }, {"type": "divider"}, { "type": "actions", "elements": [ { "type": "button", "text": {"type": "plain_text", "text": confirm_text}, "style": "primary", "action_id": confirm_action_id, }, { "type": "button", "text": {"type": "plain_text", "text": reject_text}, "style": "danger", "action_id": reject_action_id, }, ], }, ] def build_poll_blocks( question: str, options: list[str], poll_id: str, ) -> list[dict[str, Any]]: blocks: list[dict[str, Any]] = [ { "type": "header", "text": {"type": "plain_text", "text": "📊 投票"}, }, { "type": "section", "text": {"type": "mrkdwn", "text": f"*{question}*"}, }, {"type": "divider"}, ] for i, option in enumerate(options): blocks.append( { "type": "section", "text": {"type": "mrkdwn", "text": option}, "accessory": { "type": "button", "text": {"type": "plain_text", "text": "投票"}, "action_id": f"poll_{poll_id}_{i}", "value": str(i), }, } ) return blocks def build_error_notice(message: str) -> list[dict[str, Any]]: return [ { "type": "section", "text": {"type": "mrkdwn", "text": f":warning: *错误*\n>{message}"}, }, { "type": "context", "elements": [ {"type": "mrkdwn", "text": "如需帮助,请联系管理员。"}, ], }, ] def build_header(text: str, *, emoji: bool = True) -> dict[str, Any]: title = text if emoji and not any(ord(c) > 127 for c in text): title = f"📌 {text}" return { "type": "header", "text": {"type": "plain_text", "text": title}, } def build_context(*elements: dict[str, Any]) -> dict[str, Any]: return { "type": "context", "elements": list(elements), } def build_image_block(image_url: str, alt_text: str, *, title: str = "") -> dict[str, Any]: block: dict[str, Any] = { "type": "image", "image_url": image_url, "alt_text": alt_text, } if title: block["title"] = {"type": "plain_text", "text": title} return block def build_option(text: str, value: str, *, description: str = "", url: str = "") -> dict[str, Any]: option: dict[str, Any] = { "text": {"type": "plain_text", "text": text}, "value": value, } if description: option["description"] = {"type": "plain_text", "text": description} if url: option["url"] = url return option def build_option_group(label: str, *options: dict[str, Any]) -> dict[str, Any]: return { "label": {"type": "plain_text", "text": label}, "options": list(options), } def build_static_select( action_id: str, *options: dict[str, Any], placeholder: str = "选择一个选项", option_groups: list[dict[str, Any]] | None = None, ) -> dict[str, Any]: select: dict[str, Any] = { "type": "static_select", "action_id": action_id, "placeholder": {"type": "plain_text", "text": placeholder}, } if option_groups: select["option_groups"] = option_groups else: select["options"] = list(options) return select def build_users_select( action_id: str, *, placeholder: str = "选择用户", initial_user: str = "", ) -> dict[str, Any]: select: dict[str, Any] = { "type": "users_select", "action_id": action_id, "placeholder": {"type": "plain_text", "text": placeholder}, } if initial_user: select["initial_user"] = initial_user return select def build_external_select( action_id: str, *, placeholder: str = "搜索...", min_query_length: int = 1, initial_option: dict[str, Any] | None = None, ) -> dict[str, Any]: select: dict[str, Any] = { "type": "external_select", "action_id": action_id, "placeholder": {"type": "plain_text", "text": placeholder}, "min_query_length": min_query_length, } if initial_option: select["initial_option"] = initial_option return select def build_conversations_select( action_id: str, *, placeholder: str = "选择频道", ) -> dict[str, Any]: return { "type": "conversations_select", "action_id": action_id, "placeholder": {"type": "plain_text", "text": placeholder}, } def build_input( label: str, element: dict[str, Any], *, block_id: str = "", hint: str = "", optional: bool = False, dispatch_action: bool = False, ) -> dict[str, Any]: block: dict[str, Any] = { "type": "input", "label": {"type": "plain_text", "text": label}, "element": element, } if block_id: block["block_id"] = block_id if hint: block["hint"] = {"type": "plain_text", "text": hint} block["optional"] = optional if dispatch_action: block["dispatch_action"] = True return block