44from pydantic import BaseModel , Field
55from .groups import GroupParticipant
66
7+ # NOTE: All webhook event model fields are now optional to handle the dynamic
8+ # nature of webhook events. Different webhook events may contain different
9+ # subsets of fields, so making them optional allows for more flexible parsing
10+ # without validation errors.
11+
712WEBHOOK_SIGNATURE_HEADER = 'x-webhook-signature'
813
914def verify_wasender_webhook_signature (
@@ -51,9 +56,9 @@ class WasenderWebhookEventType(str, Enum):
5156DataType = TypeVar ('DataType' )
5257
5358class BaseWebhookEvent (BaseModel , Generic [EventType , DataType ]):
54- event : EventType
59+ event : Optional [ EventType ] = None
5560 timestamp : Optional [int ] = None
56- data : DataType
61+ data : Optional [ DataType ] = None
5762 session_id : Optional [str ] = Field (None , alias = "sessionId" )
5863
5964 def __getitem__ (self , key : str ) -> Any :
@@ -66,14 +71,14 @@ def __getitem__(self, key: str) -> Any:
6671 raise KeyError (key )
6772
6873class MessageKey (BaseModel ):
69- id : str
70- from_me : bool = Field (... , alias = "fromMe" )
71- remote_jid : str = Field (... , alias = "remoteJid" )
74+ id : Optional [ str ] = None
75+ from_me : Optional [ bool ] = Field (None , alias = "fromMe" )
76+ remote_jid : Optional [ str ] = Field (None , alias = "remoteJid" )
7277 participant : Optional [str ] = None
7378
7479# Chat Event Models
7580class ChatEntry (BaseModel ):
76- id : str
81+ id : Optional [ str ] = None
7782 name : Optional [str ] = None
7883 conversation_timestamp : Optional [int ] = Field (None , alias = "conversationTimestamp" )
7984 unread_count : Optional [int ] = Field (None , alias = "unreadCount" )
@@ -82,8 +87,8 @@ class ChatEntry(BaseModel):
8287
8388# Group Event Models
8489class GroupMetadata (BaseModel ):
85- jid : str
86- subject : str
90+ jid : Optional [ str ] = None
91+ subject : Optional [ str ] = None
8792 creation : Optional [int ] = None
8893 owner : Optional [str ] = None
8994 desc : Optional [str ] = None
@@ -92,13 +97,13 @@ class GroupMetadata(BaseModel):
9297 restrict : Optional [bool ] = None
9398
9499class GroupParticipantsUpdateData (BaseModel ):
95- jid : str
96- participants : List [Union [str , GroupParticipant ]]
97- action : Literal ['add' , 'remove' , 'promote' , 'demote' ]
100+ jid : Optional [ str ] = None
101+ participants : Optional [ List [Union [str , GroupParticipant ]]] = None
102+ action : Optional [ Literal ['add' , 'remove' , 'promote' , 'demote' ]] = None
98103
99104# Contact Event Models
100105class ContactEntry (BaseModel ):
101- jid : str
106+ jid : Optional [ str ] = None
102107 name : Optional [str ] = None
103108 notify : Optional [str ] = None
104109 verified_name : Optional [str ] = Field (None , alias = "verifiedName" )
@@ -117,54 +122,54 @@ class MessageContent(BaseModel):
117122 location_message : Optional [Dict [str , Any ]] = Field (None , alias = "locationMessage" )
118123
119124class MessagesUpsertData (BaseModel ):
120- key : MessageKey
125+ key : Optional [ MessageKey ] = None
121126 message : Optional [MessageContent ] = None
122127 push_name : Optional [str ] = Field (None , alias = "pushName" )
123128 message_timestamp : Optional [int ] = Field (None , alias = "messageTimestamp" )
124129
125130class MessageUpdate (BaseModel ):
126- status : str
131+ status : Optional [ str ] = None
127132
128133class MessagesUpdateDataEntry (BaseModel ):
129- key : MessageKey
130- update : MessageUpdate
134+ key : Optional [ MessageKey ] = None
135+ update : Optional [ MessageUpdate ] = None
131136
132137class MessagesDeleteData (BaseModel ):
133- keys : List [MessageKey ]
138+ keys : Optional [ List [MessageKey ]] = None
134139
135140class Reaction (BaseModel ):
136- text : str
137- key : MessageKey
141+ text : Optional [ str ] = None
142+ key : Optional [ MessageKey ] = None
138143 sender_timestamp_ms : Optional [str ] = Field (None , alias = "senderTimestampMs" )
139144 read : Optional [bool ] = None
140145
141146class MessagesReactionDataEntry (BaseModel ):
142- key : MessageKey
143- reaction : Reaction
147+ key : Optional [ MessageKey ] = None
148+ reaction : Optional [ Reaction ] = None
144149
145150# Message Receipt Models
146151class Receipt (BaseModel ):
147- user_jid : str = Field (... , alias = "userJid" )
148- status : str
152+ user_jid : Optional [ str ] = Field (None , alias = "userJid" )
153+ status : Optional [ str ] = None
149154 t : Optional [int ] = None
150155
151156class MessageReceiptUpdateDataEntry (BaseModel ):
152- key : MessageKey
153- receipt : Receipt
157+ key : Optional [ MessageKey ] = None
158+ receipt : Optional [ Receipt ] = None
154159
155160# Session Event Models
156161class MessageSentData (BaseModel ):
157- key : MessageKey
162+ key : Optional [ MessageKey ] = None
158163 message : Optional [MessageContent ] = None
159164 status : Optional [str ] = None
160165
161166class SessionStatusData (BaseModel ):
162- status : Literal ["CONNECTED" , "DISCONNECTED" , "NEED_SCAN" , "CONNECTING" , "LOGGED_OUT" , "EXPIRED" ]
167+ status : Optional [ Literal ["CONNECTED" , "DISCONNECTED" , "NEED_SCAN" , "CONNECTING" , "LOGGED_OUT" , "EXPIRED" ]] = None
163168 session_id : Optional [str ] = Field (None , alias = "sessionId" )
164169 reason : Optional [str ] = None
165170
166171class QrCodeUpdatedData (BaseModel ):
167- qr : str
172+ qr : Optional [ str ] = None
168173 session_id : Optional [str ] = Field (None , alias = "sessionId" )
169174
170175# Define specific event types using the generic BaseWebhookEvent
@@ -196,22 +201,4 @@ class QrCodeUpdatedData(BaseModel):
196201 ContactsUpsertEvent , ContactsUpdateEvent ,
197202 MessagesUpsertEvent , MessagesUpdateEvent , MessagesDeleteEvent , MessagesReactionEvent ,
198203 MessageReceiptUpdateEvent , MessageSentEvent , SessionStatusEvent , QrCodeUpdatedEvent
199- ]
200-
201- # Helper types for partial updates if needed (conceptual)
202- class PartialChatEntry (ChatEntry ):
203- id : Optional [str ] = None
204- name : Optional [str ] = None
205- conversation_timestamp : Optional [int ] = Field (None , alias = "conversationTimestamp" )
206- unread_count : Optional [int ] = Field (None , alias = "unreadCount" )
207- mute_end_time : Optional [int ] = Field (None , alias = "muteEndTime" )
208- is_spam : Optional [bool ] = Field (None , alias = "isSpam" )
209-
210- class PartialGroupMetadata (GroupMetadata ):
211- jid : Optional [str ] = None
212- subject : Optional [str ] = None
213- # ... make other fields optional
214-
215- class PartialContactEntry (ContactEntry ):
216- jid : Optional [str ] = None
217- # ... make other fields optional
204+ ]
0 commit comments