ForcePilot/backend/package/yuxi/channels/adapters/mattermost/polls.py
Kris 002d601d1b feat(mattermost): 实现完整的 Mattermost 适配器模块
新增 Mattermost 渠道完整实现,包含适配器核心、消息处理、交互回调、命令支持、安全校验、多账号管理等功能,支持机器人消息发送、交互按钮、命令注册、投票功能以及配置动态修改等特性。
2026-05-12 00:46:12 +08:00

111 lines
3.1 KiB
Python
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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", ""),
}