wappa 0.1.9__py3-none-any.whl → 0.1.10__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of wappa might be problematic. Click here for more details.
- wappa/__init__.py +4 -5
- wappa/api/controllers/webhook_controller.py +5 -2
- wappa/api/dependencies/__init__.py +0 -5
- wappa/api/middleware/error_handler.py +4 -4
- wappa/api/middleware/owner.py +11 -5
- wappa/api/routes/webhooks.py +2 -2
- wappa/cli/__init__.py +1 -1
- wappa/cli/examples/init/app/main.py +2 -1
- wappa/cli/examples/init/app/master_event.py +5 -3
- wappa/cli/examples/json_cache_example/app/__init__.py +1 -1
- wappa/cli/examples/json_cache_example/app/main.py +56 -44
- wappa/cli/examples/json_cache_example/app/master_event.py +181 -145
- wappa/cli/examples/json_cache_example/app/models/__init__.py +1 -1
- wappa/cli/examples/json_cache_example/app/models/json_demo_models.py +32 -51
- wappa/cli/examples/json_cache_example/app/scores/__init__.py +2 -2
- wappa/cli/examples/json_cache_example/app/scores/score_base.py +52 -46
- wappa/cli/examples/json_cache_example/app/scores/score_cache_statistics.py +70 -62
- wappa/cli/examples/json_cache_example/app/scores/score_message_history.py +41 -44
- wappa/cli/examples/json_cache_example/app/scores/score_state_commands.py +83 -71
- wappa/cli/examples/json_cache_example/app/scores/score_user_management.py +73 -57
- wappa/cli/examples/json_cache_example/app/utils/__init__.py +2 -2
- wappa/cli/examples/json_cache_example/app/utils/cache_utils.py +54 -56
- wappa/cli/examples/json_cache_example/app/utils/message_utils.py +85 -80
- wappa/cli/examples/openai_transcript/app/main.py +2 -1
- wappa/cli/examples/openai_transcript/app/master_event.py +31 -22
- wappa/cli/examples/openai_transcript/app/openai_utils/__init__.py +1 -1
- wappa/cli/examples/openai_transcript/app/openai_utils/audio_processing.py +37 -24
- wappa/cli/examples/redis_cache_example/app/__init__.py +1 -1
- wappa/cli/examples/redis_cache_example/app/main.py +56 -44
- wappa/cli/examples/redis_cache_example/app/master_event.py +181 -145
- wappa/cli/examples/redis_cache_example/app/models/redis_demo_models.py +31 -50
- wappa/cli/examples/redis_cache_example/app/scores/__init__.py +2 -2
- wappa/cli/examples/redis_cache_example/app/scores/score_base.py +52 -46
- wappa/cli/examples/redis_cache_example/app/scores/score_cache_statistics.py +70 -62
- wappa/cli/examples/redis_cache_example/app/scores/score_message_history.py +41 -44
- wappa/cli/examples/redis_cache_example/app/scores/score_state_commands.py +83 -71
- wappa/cli/examples/redis_cache_example/app/scores/score_user_management.py +73 -57
- wappa/cli/examples/redis_cache_example/app/utils/__init__.py +2 -2
- wappa/cli/examples/redis_cache_example/app/utils/cache_utils.py +54 -56
- wappa/cli/examples/redis_cache_example/app/utils/message_utils.py +85 -80
- wappa/cli/examples/simple_echo_example/app/__init__.py +1 -1
- wappa/cli/examples/simple_echo_example/app/main.py +41 -33
- wappa/cli/examples/simple_echo_example/app/master_event.py +78 -57
- wappa/cli/examples/wappa_full_example/app/__init__.py +1 -1
- wappa/cli/examples/wappa_full_example/app/handlers/__init__.py +1 -1
- wappa/cli/examples/wappa_full_example/app/handlers/command_handlers.py +134 -126
- wappa/cli/examples/wappa_full_example/app/handlers/message_handlers.py +237 -229
- wappa/cli/examples/wappa_full_example/app/handlers/state_handlers.py +170 -148
- wappa/cli/examples/wappa_full_example/app/main.py +51 -39
- wappa/cli/examples/wappa_full_example/app/master_event.py +179 -120
- wappa/cli/examples/wappa_full_example/app/models/__init__.py +1 -1
- wappa/cli/examples/wappa_full_example/app/models/state_models.py +113 -104
- wappa/cli/examples/wappa_full_example/app/models/user_models.py +92 -76
- wappa/cli/examples/wappa_full_example/app/models/webhook_metadata.py +109 -83
- wappa/cli/examples/wappa_full_example/app/utils/__init__.py +1 -1
- wappa/cli/examples/wappa_full_example/app/utils/cache_utils.py +132 -113
- wappa/cli/examples/wappa_full_example/app/utils/media_handler.py +175 -132
- wappa/cli/examples/wappa_full_example/app/utils/metadata_extractor.py +126 -87
- wappa/cli/main.py +9 -4
- wappa/core/__init__.py +18 -23
- wappa/core/config/settings.py +7 -5
- wappa/core/events/default_handlers.py +1 -1
- wappa/core/factory/wappa_builder.py +38 -25
- wappa/core/plugins/redis_plugin.py +1 -3
- wappa/core/plugins/wappa_core_plugin.py +7 -6
- wappa/core/types.py +12 -12
- wappa/core/wappa_app.py +10 -8
- wappa/database/__init__.py +3 -4
- wappa/domain/enums/messenger_platform.py +1 -2
- wappa/domain/factories/media_factory.py +5 -20
- wappa/domain/factories/message_factory.py +5 -20
- wappa/domain/factories/messenger_factory.py +2 -4
- wappa/domain/interfaces/cache_interface.py +7 -7
- wappa/domain/interfaces/media_interface.py +2 -5
- wappa/domain/models/media_result.py +1 -3
- wappa/domain/models/platforms/platform_config.py +1 -3
- wappa/messaging/__init__.py +9 -12
- wappa/messaging/whatsapp/handlers/whatsapp_media_handler.py +20 -22
- wappa/models/__init__.py +27 -35
- wappa/persistence/__init__.py +12 -15
- wappa/persistence/cache_factory.py +0 -1
- wappa/persistence/json/__init__.py +1 -1
- wappa/persistence/json/cache_adapters.py +37 -25
- wappa/persistence/json/handlers/state_handler.py +60 -52
- wappa/persistence/json/handlers/table_handler.py +51 -49
- wappa/persistence/json/handlers/user_handler.py +71 -55
- wappa/persistence/json/handlers/utils/file_manager.py +42 -39
- wappa/persistence/json/handlers/utils/key_factory.py +1 -1
- wappa/persistence/json/handlers/utils/serialization.py +13 -11
- wappa/persistence/json/json_cache_factory.py +4 -8
- wappa/persistence/json/storage_manager.py +66 -79
- wappa/persistence/memory/__init__.py +1 -1
- wappa/persistence/memory/cache_adapters.py +37 -25
- wappa/persistence/memory/handlers/state_handler.py +62 -52
- wappa/persistence/memory/handlers/table_handler.py +59 -53
- wappa/persistence/memory/handlers/user_handler.py +75 -55
- wappa/persistence/memory/handlers/utils/key_factory.py +1 -1
- wappa/persistence/memory/handlers/utils/memory_store.py +75 -71
- wappa/persistence/memory/handlers/utils/ttl_manager.py +59 -67
- wappa/persistence/memory/memory_cache_factory.py +3 -7
- wappa/persistence/memory/storage_manager.py +52 -62
- wappa/persistence/redis/cache_adapters.py +27 -21
- wappa/persistence/redis/ops.py +11 -11
- wappa/persistence/redis/redis_client.py +4 -6
- wappa/persistence/redis/redis_manager.py +12 -4
- wappa/processors/factory.py +5 -5
- wappa/schemas/factory.py +2 -5
- wappa/schemas/whatsapp/message_types/errors.py +3 -12
- wappa/schemas/whatsapp/validators.py +3 -3
- wappa/webhooks/__init__.py +17 -18
- wappa/webhooks/factory.py +3 -5
- wappa/webhooks/whatsapp/__init__.py +10 -13
- wappa/webhooks/whatsapp/message_types/audio.py +0 -4
- wappa/webhooks/whatsapp/message_types/document.py +1 -9
- wappa/webhooks/whatsapp/message_types/errors.py +3 -12
- wappa/webhooks/whatsapp/message_types/location.py +1 -21
- wappa/webhooks/whatsapp/message_types/sticker.py +1 -5
- wappa/webhooks/whatsapp/message_types/text.py +0 -6
- wappa/webhooks/whatsapp/message_types/video.py +1 -20
- wappa/webhooks/whatsapp/status_models.py +2 -2
- wappa/webhooks/whatsapp/validators.py +3 -3
- {wappa-0.1.9.dist-info → wappa-0.1.10.dist-info}/METADATA +362 -8
- {wappa-0.1.9.dist-info → wappa-0.1.10.dist-info}/RECORD +126 -126
- {wappa-0.1.9.dist-info → wappa-0.1.10.dist-info}/WHEEL +0 -0
- {wappa-0.1.9.dist-info → wappa-0.1.10.dist-info}/entry_points.txt +0 -0
- {wappa-0.1.9.dist-info → wappa-0.1.10.dist-info}/licenses/LICENSE +0 -0
|
@@ -7,13 +7,14 @@ objects to provide comprehensive information about each message type.
|
|
|
7
7
|
|
|
8
8
|
from datetime import datetime
|
|
9
9
|
from enum import Enum
|
|
10
|
-
from typing import Any
|
|
10
|
+
from typing import Any
|
|
11
11
|
|
|
12
12
|
from pydantic import BaseModel, Field
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
class MessageType(str, Enum):
|
|
16
16
|
"""Supported message types for metadata extraction."""
|
|
17
|
+
|
|
17
18
|
TEXT = "text"
|
|
18
19
|
IMAGE = "image"
|
|
19
20
|
VIDEO = "video"
|
|
@@ -30,33 +31,37 @@ class MessageType(str, Enum):
|
|
|
30
31
|
|
|
31
32
|
class BaseMessageMetadata(BaseModel):
|
|
32
33
|
"""Base metadata common to all message types."""
|
|
34
|
+
|
|
33
35
|
message_id: str
|
|
34
36
|
message_type: MessageType
|
|
35
37
|
timestamp: datetime
|
|
36
38
|
user_id: str
|
|
37
|
-
user_name:
|
|
39
|
+
user_name: str | None = None
|
|
38
40
|
tenant_id: str
|
|
39
41
|
platform: str
|
|
40
|
-
|
|
42
|
+
|
|
41
43
|
# Processing metadata
|
|
42
|
-
processing_time_ms:
|
|
44
|
+
processing_time_ms: int | None = None
|
|
43
45
|
cache_hit: bool = False
|
|
44
|
-
|
|
46
|
+
|
|
45
47
|
class Config:
|
|
46
48
|
use_enum_values = True
|
|
47
49
|
|
|
48
50
|
|
|
49
51
|
class TextMessageMetadata(BaseMessageMetadata):
|
|
50
52
|
"""Metadata specific to text messages."""
|
|
53
|
+
|
|
51
54
|
message_type: MessageType = MessageType.TEXT
|
|
52
55
|
text_content: str
|
|
53
56
|
text_length: int
|
|
54
57
|
has_urls: bool = False
|
|
55
58
|
has_mentions: bool = False
|
|
56
59
|
is_forwarded: bool = False
|
|
57
|
-
|
|
60
|
+
|
|
58
61
|
@classmethod
|
|
59
|
-
def from_webhook(
|
|
62
|
+
def from_webhook(
|
|
63
|
+
cls, webhook, processing_time_ms: int = None
|
|
64
|
+
) -> "TextMessageMetadata":
|
|
60
65
|
"""Create TextMessageMetadata from IncomingMessageWebhook."""
|
|
61
66
|
text_content = webhook.get_message_text() or ""
|
|
62
67
|
return cls(
|
|
@@ -71,43 +76,48 @@ class TextMessageMetadata(BaseMessageMetadata):
|
|
|
71
76
|
has_urls="http" in text_content.lower(),
|
|
72
77
|
has_mentions="@" in text_content,
|
|
73
78
|
is_forwarded=webhook.was_forwarded(),
|
|
74
|
-
processing_time_ms=processing_time_ms
|
|
79
|
+
processing_time_ms=processing_time_ms,
|
|
75
80
|
)
|
|
76
81
|
|
|
77
82
|
|
|
78
83
|
class MediaMessageMetadata(BaseMessageMetadata):
|
|
79
84
|
"""Metadata specific to media messages (image, video, audio, document)."""
|
|
85
|
+
|
|
80
86
|
media_id: str
|
|
81
87
|
media_type: str
|
|
82
|
-
file_size:
|
|
83
|
-
mime_type:
|
|
84
|
-
caption:
|
|
88
|
+
file_size: int | None = None
|
|
89
|
+
mime_type: str | None = None
|
|
90
|
+
caption: str | None = None
|
|
85
91
|
caption_length: int = 0
|
|
86
92
|
is_forwarded: bool = False
|
|
87
|
-
|
|
93
|
+
|
|
88
94
|
# Media-specific fields
|
|
89
|
-
width:
|
|
90
|
-
height:
|
|
91
|
-
duration:
|
|
92
|
-
filename:
|
|
93
|
-
|
|
95
|
+
width: int | None = None
|
|
96
|
+
height: int | None = None
|
|
97
|
+
duration: int | None = None # For video/audio
|
|
98
|
+
filename: str | None = None # For documents
|
|
99
|
+
|
|
94
100
|
@classmethod
|
|
95
|
-
def from_webhook(
|
|
101
|
+
def from_webhook(
|
|
102
|
+
cls, webhook, message_type: MessageType, processing_time_ms: int = None
|
|
103
|
+
) -> "MediaMessageMetadata":
|
|
96
104
|
"""Create MediaMessageMetadata from IncomingMessageWebhook."""
|
|
97
105
|
# Extract media information from webhook
|
|
98
|
-
media_id = getattr(webhook.message,
|
|
99
|
-
|
|
100
|
-
|
|
106
|
+
media_id = getattr(webhook.message, "media_id", "") or getattr(
|
|
107
|
+
webhook.message, "id", ""
|
|
108
|
+
)
|
|
109
|
+
caption = getattr(webhook.message, "caption", "") or ""
|
|
110
|
+
|
|
101
111
|
# Try to get additional media properties
|
|
102
|
-
mime_type = getattr(webhook.message,
|
|
103
|
-
file_size = getattr(webhook.message,
|
|
104
|
-
filename = getattr(webhook.message,
|
|
105
|
-
|
|
112
|
+
mime_type = getattr(webhook.message, "mime_type", None)
|
|
113
|
+
file_size = getattr(webhook.message, "file_size", None)
|
|
114
|
+
filename = getattr(webhook.message, "filename", None)
|
|
115
|
+
|
|
106
116
|
# For images/videos
|
|
107
|
-
width = getattr(webhook.message,
|
|
108
|
-
height = getattr(webhook.message,
|
|
109
|
-
duration = getattr(webhook.message,
|
|
110
|
-
|
|
117
|
+
width = getattr(webhook.message, "width", None)
|
|
118
|
+
height = getattr(webhook.message, "height", None)
|
|
119
|
+
duration = getattr(webhook.message, "duration", None)
|
|
120
|
+
|
|
111
121
|
return cls(
|
|
112
122
|
message_id=webhook.message.message_id,
|
|
113
123
|
message_type=message_type,
|
|
@@ -127,28 +137,31 @@ class MediaMessageMetadata(BaseMessageMetadata):
|
|
|
127
137
|
height=height,
|
|
128
138
|
duration=duration,
|
|
129
139
|
is_forwarded=webhook.was_forwarded(),
|
|
130
|
-
processing_time_ms=processing_time_ms
|
|
140
|
+
processing_time_ms=processing_time_ms,
|
|
131
141
|
)
|
|
132
142
|
|
|
133
143
|
|
|
134
144
|
class LocationMessageMetadata(BaseMessageMetadata):
|
|
135
145
|
"""Metadata specific to location messages."""
|
|
146
|
+
|
|
136
147
|
message_type: MessageType = MessageType.LOCATION
|
|
137
148
|
latitude: float
|
|
138
149
|
longitude: float
|
|
139
|
-
location_name:
|
|
140
|
-
location_address:
|
|
150
|
+
location_name: str | None = None
|
|
151
|
+
location_address: str | None = None
|
|
141
152
|
is_forwarded: bool = False
|
|
142
|
-
|
|
153
|
+
|
|
143
154
|
@classmethod
|
|
144
|
-
def from_webhook(
|
|
155
|
+
def from_webhook(
|
|
156
|
+
cls, webhook, processing_time_ms: int = None
|
|
157
|
+
) -> "LocationMessageMetadata":
|
|
145
158
|
"""Create LocationMessageMetadata from IncomingMessageWebhook."""
|
|
146
159
|
# Extract location data from webhook
|
|
147
|
-
latitude = getattr(webhook.message,
|
|
148
|
-
longitude = getattr(webhook.message,
|
|
149
|
-
location_name = getattr(webhook.message,
|
|
150
|
-
location_address = getattr(webhook.message,
|
|
151
|
-
|
|
160
|
+
latitude = getattr(webhook.message, "latitude", 0.0)
|
|
161
|
+
longitude = getattr(webhook.message, "longitude", 0.0)
|
|
162
|
+
location_name = getattr(webhook.message, "name", None)
|
|
163
|
+
location_address = getattr(webhook.message, "address", None)
|
|
164
|
+
|
|
152
165
|
return cls(
|
|
153
166
|
message_id=webhook.message.message_id,
|
|
154
167
|
timestamp=webhook.timestamp,
|
|
@@ -161,47 +174,50 @@ class LocationMessageMetadata(BaseMessageMetadata):
|
|
|
161
174
|
location_name=location_name,
|
|
162
175
|
location_address=location_address,
|
|
163
176
|
is_forwarded=webhook.was_forwarded(),
|
|
164
|
-
processing_time_ms=processing_time_ms
|
|
177
|
+
processing_time_ms=processing_time_ms,
|
|
165
178
|
)
|
|
166
179
|
|
|
167
180
|
|
|
168
181
|
class ContactMessageMetadata(BaseMessageMetadata):
|
|
169
182
|
"""Metadata specific to contact messages."""
|
|
183
|
+
|
|
170
184
|
message_type: MessageType = MessageType.CONTACT
|
|
171
185
|
contacts_count: int
|
|
172
|
-
contact_names:
|
|
186
|
+
contact_names: list[str] = Field(default_factory=list)
|
|
173
187
|
has_phone_numbers: bool = False
|
|
174
188
|
has_emails: bool = False
|
|
175
189
|
is_forwarded: bool = False
|
|
176
|
-
|
|
190
|
+
|
|
177
191
|
@classmethod
|
|
178
|
-
def from_webhook(
|
|
192
|
+
def from_webhook(
|
|
193
|
+
cls, webhook, processing_time_ms: int = None
|
|
194
|
+
) -> "ContactMessageMetadata":
|
|
179
195
|
"""Create ContactMessageMetadata from IncomingMessageWebhook."""
|
|
180
196
|
# Extract contact data from webhook
|
|
181
|
-
contacts = getattr(webhook.message,
|
|
197
|
+
contacts = getattr(webhook.message, "contacts", [])
|
|
182
198
|
if not isinstance(contacts, list):
|
|
183
199
|
contacts = [contacts] if contacts else []
|
|
184
|
-
|
|
200
|
+
|
|
185
201
|
contact_names = []
|
|
186
202
|
has_phone_numbers = False
|
|
187
203
|
has_emails = False
|
|
188
|
-
|
|
204
|
+
|
|
189
205
|
for contact in contacts:
|
|
190
206
|
# Extract contact name
|
|
191
|
-
if hasattr(contact,
|
|
192
|
-
if hasattr(contact.name,
|
|
207
|
+
if hasattr(contact, "name") and contact.name:
|
|
208
|
+
if hasattr(contact.name, "formatted_name"):
|
|
193
209
|
contact_names.append(contact.name.formatted_name)
|
|
194
210
|
else:
|
|
195
211
|
contact_names.append(str(contact.name))
|
|
196
|
-
|
|
212
|
+
|
|
197
213
|
# Check for phone numbers
|
|
198
|
-
if hasattr(contact,
|
|
214
|
+
if hasattr(contact, "phones") and contact.phones:
|
|
199
215
|
has_phone_numbers = True
|
|
200
|
-
|
|
216
|
+
|
|
201
217
|
# Check for emails
|
|
202
|
-
if hasattr(contact,
|
|
218
|
+
if hasattr(contact, "emails") and contact.emails:
|
|
203
219
|
has_emails = True
|
|
204
|
-
|
|
220
|
+
|
|
205
221
|
return cls(
|
|
206
222
|
message_id=webhook.message.message_id,
|
|
207
223
|
timestamp=webhook.timestamp,
|
|
@@ -214,43 +230,50 @@ class ContactMessageMetadata(BaseMessageMetadata):
|
|
|
214
230
|
has_phone_numbers=has_phone_numbers,
|
|
215
231
|
has_emails=has_emails,
|
|
216
232
|
is_forwarded=webhook.was_forwarded(),
|
|
217
|
-
processing_time_ms=processing_time_ms
|
|
233
|
+
processing_time_ms=processing_time_ms,
|
|
218
234
|
)
|
|
219
235
|
|
|
220
236
|
|
|
221
237
|
class InteractiveMessageMetadata(BaseMessageMetadata):
|
|
222
238
|
"""Metadata specific to interactive messages (button/list selections)."""
|
|
239
|
+
|
|
223
240
|
message_type: MessageType = MessageType.INTERACTIVE
|
|
224
241
|
interaction_type: str # button_reply, list_reply
|
|
225
242
|
selection_id: str
|
|
226
|
-
selection_title:
|
|
227
|
-
context_message_id:
|
|
228
|
-
|
|
243
|
+
selection_title: str | None = None
|
|
244
|
+
context_message_id: str | None = None # Original message that triggered this
|
|
245
|
+
|
|
229
246
|
@classmethod
|
|
230
|
-
def from_webhook(
|
|
247
|
+
def from_webhook(
|
|
248
|
+
cls, webhook, processing_time_ms: int = None
|
|
249
|
+
) -> "InteractiveMessageMetadata":
|
|
231
250
|
"""Create InteractiveMessageMetadata from IncomingMessageWebhook."""
|
|
232
251
|
# Extract interactive data
|
|
233
252
|
selection_id = webhook.get_interactive_selection() or ""
|
|
234
253
|
interaction_type = "unknown"
|
|
235
254
|
selection_title = None
|
|
236
|
-
|
|
255
|
+
|
|
237
256
|
# Try to determine interaction type and get more details
|
|
238
|
-
if hasattr(webhook.message,
|
|
257
|
+
if hasattr(webhook.message, "interactive") and webhook.message.interactive:
|
|
239
258
|
interactive_data = webhook.message.interactive
|
|
240
|
-
|
|
241
|
-
if hasattr(interactive_data,
|
|
259
|
+
|
|
260
|
+
if hasattr(interactive_data, "type"):
|
|
242
261
|
interaction_type = interactive_data.type
|
|
243
|
-
|
|
262
|
+
|
|
244
263
|
# Get button reply details
|
|
245
|
-
if interaction_type == "button_reply" and hasattr(
|
|
264
|
+
if interaction_type == "button_reply" and hasattr(
|
|
265
|
+
interactive_data, "button_reply"
|
|
266
|
+
):
|
|
246
267
|
button_reply = interactive_data.button_reply
|
|
247
|
-
selection_title = getattr(button_reply,
|
|
248
|
-
|
|
268
|
+
selection_title = getattr(button_reply, "title", None)
|
|
269
|
+
|
|
249
270
|
# Get list reply details
|
|
250
|
-
elif interaction_type == "list_reply" and hasattr(
|
|
271
|
+
elif interaction_type == "list_reply" and hasattr(
|
|
272
|
+
interactive_data, "list_reply"
|
|
273
|
+
):
|
|
251
274
|
list_reply = interactive_data.list_reply
|
|
252
|
-
selection_title = getattr(list_reply,
|
|
253
|
-
|
|
275
|
+
selection_title = getattr(list_reply, "title", None)
|
|
276
|
+
|
|
254
277
|
return cls(
|
|
255
278
|
message_id=webhook.message.message_id,
|
|
256
279
|
timestamp=webhook.timestamp,
|
|
@@ -261,23 +284,26 @@ class InteractiveMessageMetadata(BaseMessageMetadata):
|
|
|
261
284
|
interaction_type=interaction_type,
|
|
262
285
|
selection_id=selection_id,
|
|
263
286
|
selection_title=selection_title,
|
|
264
|
-
processing_time_ms=processing_time_ms
|
|
287
|
+
processing_time_ms=processing_time_ms,
|
|
265
288
|
)
|
|
266
289
|
|
|
267
290
|
|
|
268
291
|
class UnknownMessageMetadata(BaseMessageMetadata):
|
|
269
292
|
"""Metadata for unsupported or unknown message types."""
|
|
293
|
+
|
|
270
294
|
message_type: MessageType = MessageType.UNKNOWN
|
|
271
|
-
raw_message_data:
|
|
272
|
-
|
|
295
|
+
raw_message_data: dict[str, Any] = Field(default_factory=dict)
|
|
296
|
+
|
|
273
297
|
@classmethod
|
|
274
|
-
def from_webhook(
|
|
298
|
+
def from_webhook(
|
|
299
|
+
cls, webhook, processing_time_ms: int = None
|
|
300
|
+
) -> "UnknownMessageMetadata":
|
|
275
301
|
"""Create UnknownMessageMetadata from IncomingMessageWebhook."""
|
|
276
302
|
# Capture raw message data for debugging
|
|
277
303
|
raw_data = {}
|
|
278
|
-
if hasattr(webhook.message,
|
|
304
|
+
if hasattr(webhook.message, "__dict__"):
|
|
279
305
|
raw_data = {k: str(v)[:200] for k, v in webhook.message.__dict__.items()}
|
|
280
|
-
|
|
306
|
+
|
|
281
307
|
return cls(
|
|
282
308
|
message_id=webhook.message.message_id,
|
|
283
309
|
timestamp=webhook.timestamp,
|
|
@@ -286,16 +312,16 @@ class UnknownMessageMetadata(BaseMessageMetadata):
|
|
|
286
312
|
tenant_id=webhook.tenant.get_tenant_key(),
|
|
287
313
|
platform=webhook.platform.value,
|
|
288
314
|
raw_message_data=raw_data,
|
|
289
|
-
processing_time_ms=processing_time_ms
|
|
315
|
+
processing_time_ms=processing_time_ms,
|
|
290
316
|
)
|
|
291
317
|
|
|
292
318
|
|
|
293
319
|
# Union type for all metadata models
|
|
294
320
|
WebhookMetadata = (
|
|
295
|
-
TextMessageMetadata
|
|
296
|
-
MediaMessageMetadata
|
|
297
|
-
LocationMessageMetadata
|
|
298
|
-
ContactMessageMetadata
|
|
299
|
-
InteractiveMessageMetadata
|
|
300
|
-
UnknownMessageMetadata
|
|
301
|
-
)
|
|
321
|
+
TextMessageMetadata
|
|
322
|
+
| MediaMessageMetadata
|
|
323
|
+
| LocationMessageMetadata
|
|
324
|
+
| ContactMessageMetadata
|
|
325
|
+
| InteractiveMessageMetadata
|
|
326
|
+
| UnknownMessageMetadata
|
|
327
|
+
)
|