Skip to content

Commit aa9a1d4

Browse files
committed
make webhook events type optional
1 parent 8b850a3 commit aa9a1d4

File tree

5 files changed

+35
-48
lines changed

5 files changed

+35
-48
lines changed

.coverage

0 Bytes
Binary file not shown.
0 Bytes
Binary file not shown.
-462 Bytes
Binary file not shown.

wasenderapi/_version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "0.3.0"
1+
__version__ = "0.3.1"

wasenderapi/webhook.py

Lines changed: 34 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@
44
from pydantic import BaseModel, Field
55
from .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+
712
WEBHOOK_SIGNATURE_HEADER = 'x-webhook-signature'
813

914
def verify_wasender_webhook_signature(
@@ -51,9 +56,9 @@ class WasenderWebhookEventType(str, Enum):
5156
DataType = TypeVar('DataType')
5257

5358
class 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

6873
class 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
7580
class 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
8489
class 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

9499
class 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
100105
class 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

119124
class 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

125130
class MessageUpdate(BaseModel):
126-
status: str
131+
status: Optional[str] = None
127132

128133
class MessagesUpdateDataEntry(BaseModel):
129-
key: MessageKey
130-
update: MessageUpdate
134+
key: Optional[MessageKey] = None
135+
update: Optional[MessageUpdate] = None
131136

132137
class MessagesDeleteData(BaseModel):
133-
keys: List[MessageKey]
138+
keys: Optional[List[MessageKey]] = None
134139

135140
class 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

141146
class MessagesReactionDataEntry(BaseModel):
142-
key: MessageKey
143-
reaction: Reaction
147+
key: Optional[MessageKey] = None
148+
reaction: Optional[Reaction] = None
144149

145150
# Message Receipt Models
146151
class 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

151156
class MessageReceiptUpdateDataEntry(BaseModel):
152-
key: MessageKey
153-
receipt: Receipt
157+
key: Optional[MessageKey] = None
158+
receipt: Optional[Receipt] = None
154159

155160
# Session Event Models
156161
class MessageSentData(BaseModel):
157-
key: MessageKey
162+
key: Optional[MessageKey] = None
158163
message: Optional[MessageContent] = None
159164
status: Optional[str] = None
160165

161166
class 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

166171
class 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

Comments
 (0)