from enum import StrEnum from typing import Annotated, Literal from pydantic import BaseModel, BeforeValidator, Field class EventType(StrEnum): processed = "processed" deferred = "deferred" delivered = "delivered" open = "open" click = "click" bounce = "bounce" dropped = "dropped" spamreport = "spamreport" class SendType(StrEnum): fan_reply_forwarding = "fan_reply_forwarding" 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 trigger_id: str | None = Field(None, validation_alias="automated_email_trigger_id") 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 class BounceEvent(Event): event: Literal[EventType.bounce] sg_message_id: str | None = None is_test: bool | None = None class ReplyForwardingEvent(Event): is_test: bool | None = None send_type: Literal[SendType.fan_reply_forwarding] 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