from enum import StrEnum from typing import Annotated from pydantic import BaseModel, BeforeValidator, Field class EventType(StrEnum): processed = "processed" dropped = "dropped" spamreport = "spamreport" class Event(BaseModel): event: EventType sg_event_id: str sg_message_id: str timestamp: int email: str campaign_id: str | None = None email_id: str | None = None email_type: str | None = None automated_trigger_id: str | None = None batch_id: str | None = None is_test: bool asm_group_id: int | None = None attempt: str | None = None bounce_classification: str | None = None category: list[str] | None = None ip: str | None = None reason: str | None = None response: str | None = None sg_machine_open: bool | None = None smtp_id: str | None = Field(None, validation_alias="smtp-id") status: str | None = None type: str | None = None url: str | None = None useragent: str | None = None @property def origin_id(self) -> str | None: return self.email_id or self.campaign_id class RequestHeaders(BaseModel): signature: str = Field(validation_alias="x-twilio-email-event-webhook-signature") timestamp: Annotated[str, BeforeValidator(lambda timestamp: str(timestamp))] = ( Field(validation_alias="x-twilio-email-event-webhook-timestamp") ) class Request(BaseModel): headers: RequestHeaders path: str body: str