feat(02-03): add MediaAttachment model, WhatsApp normalizer, and signature verification
- Add MediaType(StrEnum) and MediaAttachment(BaseModel) to shared/models/message.py - Add media: list[MediaAttachment] field to MessageContent - Add whatsapp_app_secret, whatsapp_verify_token, and MinIO settings to shared/config.py - Add normalize_whatsapp_event() to gateway/normalize.py (text, image, document support) - Create whatsapp.py adapter with verify_whatsapp_signature() and verify_hub_challenge() - 30 new passing tests (signature verification + normalizer)
This commit is contained in:
@@ -28,6 +28,38 @@ class ChannelType(StrEnum):
|
||||
SIGNAL = "signal"
|
||||
|
||||
|
||||
class MediaType(StrEnum):
|
||||
"""Supported media attachment types."""
|
||||
|
||||
IMAGE = "image"
|
||||
DOCUMENT = "document"
|
||||
AUDIO = "audio"
|
||||
VIDEO = "video"
|
||||
|
||||
|
||||
class MediaAttachment(BaseModel):
|
||||
"""
|
||||
A media file attached to a message (image, document, audio, or video).
|
||||
|
||||
After normalization, `url` contains a placeholder media ID URL from the
|
||||
channel's API. The channel adapter downloads the media and stores it in
|
||||
MinIO, then updates `storage_key` and `url` with the final presigned URL.
|
||||
"""
|
||||
|
||||
media_type: MediaType = Field(description="Type of media: image, document, audio, or video")
|
||||
url: str | None = Field(
|
||||
default=None,
|
||||
description="Download URL — placeholder media ID URL after normalization, presigned MinIO URL after storage",
|
||||
)
|
||||
storage_key: str | None = Field(
|
||||
default=None,
|
||||
description="MinIO object key: {tenant_id}/{agent_id}/{message_id}/{filename}",
|
||||
)
|
||||
mime_type: str | None = Field(default=None, description="MIME type (e.g. image/jpeg)")
|
||||
filename: str | None = Field(default=None, description="Original filename if available")
|
||||
size_bytes: int | None = Field(default=None, description="File size in bytes if available")
|
||||
|
||||
|
||||
class SenderInfo(BaseModel):
|
||||
"""Information about the message sender."""
|
||||
|
||||
@@ -50,6 +82,10 @@ class MessageContent(BaseModel):
|
||||
default_factory=list,
|
||||
description="List of user/bot IDs mentioned in the message",
|
||||
)
|
||||
media: list[MediaAttachment] = Field(
|
||||
default_factory=list,
|
||||
description="Typed media attachments (images, documents, audio, video)",
|
||||
)
|
||||
|
||||
|
||||
class KonstructMessage(BaseModel):
|
||||
|
||||
Reference in New Issue
Block a user