Skip to content

Instantly share code, notes, and snippets.

@mentix02
Last active August 19, 2025 03:12
Show Gist options
  • Select an option

  • Save mentix02/16f69a58036b2f3ec16c321512a1f575 to your computer and use it in GitHub Desktop.

Select an option

Save mentix02/16f69a58036b2f3ec16c321512a1f575 to your computer and use it in GitHub Desktop.
type WebhookEventAttributes = {
http_request: {
client_ip: string;
user_agent: string;
};
};
type Webhook<EvtType, Data> = {
type: EvtType;
object: 'event';
data: Data;
event_attributes: WebhookEventAttributes;
};
export type UserWebhookEvent = Webhook<'user.created' | 'user.updated', UserJSON> | Webhook<'user.deleted', DeletedObjectJSON>;
"""
Some heavy type masturbation for Clerk webhook events. Enjoy!
"""
from typing import Any, Literal, Annotated
from django.conf import settings
from pydantic import Tag, BaseModel, Discriminator
# Constants for Clerk webhook event types
type UserObjectType = Literal["user"]
type ClerkWebhookDeleteEventType = Literal["user.deleted"]
type ClerkWebhookCreateUpdateEventType = Literal["user.created", "user.updated"]
type ClerkWebhookEventType = Literal[ClerkWebhookCreateUpdateEventType, ClerkWebhookDeleteEventType]
class ClerkEmailAddressSchema(BaseModel):
email_address: str
object: Literal["email_address"] = "email_address"
class ClerkWebhookCreateUpdateDataSchema(BaseModel):
id: str
username: str | None
primary_email_address_id: str | None
email_addresses: list[ClerkEmailAddressSchema]
last_name: str | None = ""
first_name: str | None = ""
object: UserObjectType = "user"
class ClerkWebhookDeleteDataSchema(BaseModel):
id: str
deleted: bool
object: UserObjectType = "user"
def get_data_discriminator_value(v: Any) -> ClerkWebhookEventType:
if isinstance(v, dict):
return "user.deleted" if "deleted" in v else "user.created"
return "user.deleted" if hasattr(v, "deleted") else "user.created"
class ClerkWebhookEventSchema(BaseModel):
timestamp: int
type: ClerkWebhookEventType
data: Annotated[
(
Annotated[ClerkWebhookCreateUpdateDataSchema, Tag("user.created")]
| Annotated[ClerkWebhookDeleteDataSchema, Tag("user.deleted")]
),
Discriminator(get_data_discriminator_value),
]
object: Literal["event"] = "event"
instance_id: str = settings.CLERK_INSTANCE_ID
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment