112 lines
3.9 KiB
Python
112 lines
3.9 KiB
Python
from datetime import datetime
|
|
from typing import Any
|
|
|
|
from pydantic import BaseModel, Field, model_validator
|
|
|
|
|
|
class ChildConversationItem(BaseModel):
|
|
conversation_id: int
|
|
conversation_type: int
|
|
conversation_type_name: str
|
|
peer_type: str
|
|
peer_id: str
|
|
peer_name: str | None = None
|
|
last_message_preview: str | None = None
|
|
last_message_at: datetime | None = None
|
|
message_count: int
|
|
|
|
|
|
class ChildConversationListResponse(BaseModel):
|
|
items: list[ChildConversationItem]
|
|
total: int
|
|
next_cursor: int | None = None
|
|
|
|
|
|
class ChildConversationMessageItem(BaseModel):
|
|
id: int
|
|
conversation_id: int
|
|
seq: int
|
|
sender_type: str
|
|
sender_id: str
|
|
receiver_type: str
|
|
receiver_id: str
|
|
content_type: int
|
|
content_text: str | None = None
|
|
content_json: dict[str, Any] | None = None
|
|
media_file_key: str | None = None
|
|
media_duration_ms: int | None = None
|
|
media_mime_type: str | None = None
|
|
media_size_bytes: int | None = None
|
|
media_transcript_text: str | None = None
|
|
client_msg_id: str | None = None
|
|
sender_name_snapshot: str | None = None
|
|
sender_avatar_snapshot: str | None = None
|
|
receiver_name_snapshot: str | None = None
|
|
receiver_avatar_snapshot: str | None = None
|
|
ext_json: dict[str, Any] | None = None
|
|
created_at: datetime
|
|
|
|
|
|
class ChildConversationMessageListResponse(BaseModel):
|
|
conversation_id: int
|
|
has_more: bool
|
|
next_cursor_seq: int | None = None
|
|
items: list[ChildConversationMessageItem]
|
|
|
|
|
|
class BaseConversationMessageCreateRequest(BaseModel):
|
|
content_type: int = Field(ge=1, le=4)
|
|
content_text: str | None = None
|
|
content_json: dict[str, Any] | None = None
|
|
media_file_key: str | None = None
|
|
media_duration_ms: int | None = Field(default=None, ge=0)
|
|
media_mime_type: str | None = None
|
|
media_size_bytes: int | None = Field(default=None, ge=0)
|
|
media_transcript_text: str | None = None
|
|
client_msg_id: str = Field(min_length=1, max_length=64)
|
|
ext_json: dict[str, Any] | None = None
|
|
|
|
@model_validator(mode="after")
|
|
def validate_message_payload(self) -> "BaseConversationMessageCreateRequest":
|
|
if self.content_type == 1 and not self.content_text:
|
|
raise ValueError("content_text is required when content_type=1")
|
|
if self.content_type == 2 and not self.media_file_key:
|
|
raise ValueError("media_file_key is required when content_type=2")
|
|
if self.content_type == 3 and not self.media_file_key:
|
|
raise ValueError("media_file_key is required when content_type=3")
|
|
if self.content_type == 4 and self.content_json is None:
|
|
raise ValueError("content_json is required when content_type=4")
|
|
return self
|
|
|
|
|
|
class ParentChildMessageCreateRequest(BaseConversationMessageCreateRequest):
|
|
pass
|
|
|
|
|
|
class DeviceMessageCreateRequest(BaseConversationMessageCreateRequest):
|
|
conversation_type: int = Field(ge=1, le=2)
|
|
peer_child_id: int | None = Field(default=None, ge=1)
|
|
parent_user_id: int | None = Field(default=None, ge=1)
|
|
|
|
@model_validator(mode="after")
|
|
def validate_target(self) -> "DeviceMessageCreateRequest":
|
|
if self.conversation_type == 1:
|
|
if self.peer_child_id is None:
|
|
raise ValueError("peer_child_id is required when conversation_type=1")
|
|
if self.parent_user_id is not None:
|
|
raise ValueError("parent_user_id must be empty when conversation_type=1")
|
|
if self.conversation_type == 2:
|
|
if self.parent_user_id is None:
|
|
raise ValueError("parent_user_id is required when conversation_type=2")
|
|
if self.peer_child_id is not None:
|
|
raise ValueError("peer_child_id must be empty when conversation_type=2")
|
|
return self
|
|
|
|
|
|
class ConversationMessageCreateResponse(BaseModel):
|
|
idempotent: bool
|
|
conversation_id: int
|
|
conversation_type: int
|
|
conversation_type_name: str
|
|
message: ChildConversationMessageItem
|