"""Pydantic models for iMessage data structures."""
from datetime import datetime
from typing import Optional
from pydantic import BaseModel, Field
class Handle(BaseModel):
"""A contact/participant in iMessage (phone number or email)."""
rowid: int = Field(description="Database row ID")
id: str = Field(description="Phone number or email address")
service: str = Field(description="Service type: 'iMessage' or 'SMS'")
country: Optional[str] = Field(default=None, description="Country code")
class Attachment(BaseModel):
"""A media attachment in a message."""
rowid: int = Field(description="Database row ID")
guid: str = Field(description="Globally unique identifier")
filename: Optional[str] = Field(default=None, description="Full path to file")
mime_type: Optional[str] = Field(default=None, description="MIME type")
uti: Optional[str] = Field(default=None, description="Uniform Type Identifier")
total_bytes: Optional[int] = Field(default=None, description="File size in bytes")
file_uri: Optional[str] = Field(default=None, description="file:// URI to attachment")
class Message(BaseModel):
"""A single iMessage or SMS message."""
rowid: int = Field(description="Database row ID")
guid: str = Field(description="Globally unique identifier")
text: Optional[str] = Field(default=None, description="Message text content")
date: datetime = Field(description="Message timestamp (UTC)")
date_iso: str = Field(description="ISO8601 formatted date string")
timestamp_raw: int = Field(description="Raw CoreData timestamp for sorting")
is_from_me: bool = Field(description="True if sent by the user")
service: str = Field(description="Service type: 'iMessage' or 'SMS'")
handle_id: Optional[str] = Field(default=None, description="Sender phone/email")
chat_id: Optional[int] = Field(default=None, description="Associated chat row ID")
contact_name: Optional[str] = Field(default=None, description="Contact display name")
attachments: list[Attachment] = Field(
default_factory=list, description="Media attachments"
)
class Chat(BaseModel):
"""A chat/conversation (1:1 or group)."""
rowid: int = Field(description="Database row ID")
guid: str = Field(description="Globally unique identifier")
chat_identifier: str = Field(
description="Phone number, email, or group chat identifier"
)
display_name: Optional[str] = Field(
default=None, description="Display name (for group chats)"
)
service: str = Field(description="Service type extracted from GUID")
is_group: bool = Field(description="True if this is a group chat")
class Conversation(BaseModel):
"""A conversation with metadata for listing."""
chat: Chat = Field(description="The underlying chat")
participants: list[str] = Field(
default_factory=list, description="List of participant handles"
)
message_count: int = Field(description="Total number of messages")
last_message_date: Optional[datetime] = Field(
default=None, description="Timestamp of most recent message"
)
last_message_date_iso: Optional[str] = Field(
default=None, description="ISO8601 formatted last message date"
)
last_message_preview: Optional[str] = Field(
default=None, description="Preview of the last message"
)