{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://bot.yoyoo.org/schemas/v1/message-received-data.schema.json",
  "title": "MessageReceivedData",
  "description": "CloudEvent type=io.yoyoo.bot.v1.MessageReceived 时 data 字段的结构。表示用户向 Bot 发送了一条可处理消息。",
  "type": "object",
  "additionalProperties": false,
  "required": ["bot_id", "matrix", "message", "context"],
  "properties": {
    "bot_id": {
      "type": "string",
      "pattern": "^bot_[0-9A-HJKMNP-TV-Z]{26}$",
      "description": "接收消息的 Bot 平台 ID（ULID 后缀）。与 Bot 资源 id 一致。"
    },
    "matrix": {
      "type": "object",
      "additionalProperties": false,
      "required": ["room_id", "event_id", "sender_id"],
      "description": "Matrix 侧标识。开发者无需解析原始 Matrix PDU。",
      "properties": {
        "room_id": {
          "type": "string",
          "pattern": "^![^\\s:]+:[^\\s:]+$",
          "description": "Matrix 房间 ID，例如 !abc123:yoyoo.org。"
        },
        "event_id": {
          "type": "string",
          "pattern": "^\\$[^\\s:]+:[^\\s:]+$",
          "description": "触发本事件的 Matrix 事件 ID，例如 $event:yoyoo.org。回复时可用于引用（m.relates_to）。"
        },
        "sender_id": {
          "type": "string",
          "pattern": "^@[^\\s:]+:[^\\s:]+$",
          "description": "发送者 Matrix 用户 ID（MXID），例如 @alice:yoyoo.org。不含 Bot 自身。"
        }
      }
    },
    "message": {
      "type": "object",
      "additionalProperties": false,
      "required": ["body", "msgtype"],
      "description": "已归一化的消息内容。v1 以文本为主；媒体见 media 可选字段。",
      "properties": {
        "body": {
          "type": "string",
          "description": "消息正文。纯文本；若用户发送 HTML，平台可提供 plain 提取结果。"
        },
        "msgtype": {
          "type": "string",
          "enum": ["m.text", "m.notice", "m.emote"],
          "description": "对齐 Matrix m.room.message msgtype 子集。v1 入站以 m.text 为主。"
        },
        "format": {
          "type": "string",
          "enum": ["plain", "html"],
          "default": "plain",
          "description": "body 的格式提示。html 时 body 可能含安全过滤后的 HTML 片段。"
        },
        "media": {
          "type": "object",
          "additionalProperties": false,
          "description": "可选。图片/文件等媒体消息时存在。",
          "properties": {
            "msgtype": {
              "type": "string",
              "enum": ["m.image", "m.file", "m.audio", "m.video"],
              "description": "Matrix 媒体 msgtype。"
            },
            "url": {
              "type": "string",
              "format": "uri",
              "description": "平台托管或 MXC 转 HTTPS 后的临时下载 URL；有过期时间。"
            },
            "mimetype": {
              "type": "string",
              "description": "MIME 类型，例如 image/png。"
            },
            "filename": {
              "type": "string",
              "description": "原始文件名（若有）。"
            },
            "size_bytes": {
              "type": "integer",
              "minimum": 0,
              "description": "文件大小（字节）。"
            }
          },
          "required": ["msgtype", "url"]
        }
      }
    },
    "context": {
      "type": "object",
      "additionalProperties": false,
      "required": ["is_direct", "is_mention"],
      "description": "会话与触发上下文，用于权限与路由。",
      "properties": {
        "is_direct": {
          "type": "boolean",
          "description": "true 表示二人私聊（DM）；false 表示群聊/多人房间。"
        },
        "is_mention": {
          "type": "boolean",
          "description": "群聊中是否因 @Bot 或等价提及触发。私聊通常为 false。"
        },
        "thread_root_event_id": {
          "type": ["string", "null"],
          "pattern": "^\\$[^\\s:]+:[^\\s:]+$",
          "description": "若消息属于线程，则为线程根事件 ID；否则 null。"
        },
        "reply_to_event_id": {
          "type": ["string", "null"],
          "pattern": "^\\$[^\\s:]+:[^\\s:]+$",
          "description": "若用户回复某条消息，则为被回复的 event_id；否则 null。"
        }
      }
    }
  }
}
