""" Pydantic models — LINE Webhook Payload ครอบคลุม event types ที่จำเป็นสำหรับ chat conversation """ from typing import Optional, Literal from pydantic import BaseModel # ─── Source ─────────────────────────────────────────────────────────────────── class LineSource(BaseModel): type: Literal["user", "group", "room"] userId: Optional[str] = None groupId: Optional[str] = None roomId: Optional[str] = None # ─── Message ────────────────────────────────────────────────────────────────── class LineMessage(BaseModel): id: str type: Literal["text", "image", "sticker", "location", "audio", "video", "file"] text: Optional[str] = None # มีเฉพาะ type=text # ─── Events ─────────────────────────────────────────────────────────────────── class LineEvent(BaseModel): type: Literal["message", "follow", "unfollow", "join", "leave", "postback"] timestamp: int replyToken: Optional[str] = None source: LineSource message: Optional[LineMessage] = None # ─── Root Payload ───────────────────────────────────────────────────────────── class LineWebhookPayload(BaseModel): destination: str # Channel ID ปลายทาง events: list[LineEvent] # ─── Sentiment Result ───────────────────────────────────────────────────────── class SentimentResult(BaseModel): label: Literal["positive", "neutral", "negative"] score: float # confidence ของ label หลัก (0–1) raw_scores: dict[str, float] # {"positive": 0.8, "neutral": 0.1, "negative": 0.1}