letschatty 0.4.343__py3-none-any.whl → 0.4.344__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.
- letschatty/models/company/__init__.py +6 -1
- letschatty/models/company/empresa.py +2 -1
- letschatty/models/company/integrations/product_sync_status.py +28 -0
- letschatty/models/company/integrations/shopify/company_shopify_integration.py +62 -0
- letschatty/models/company/integrations/shopify/shopify_product_sync_status.py +18 -0
- letschatty/models/company/integrations/shopify/shopify_webhook_topics.py +40 -0
- letschatty/models/company/integrations/sync_status_enum.py +9 -0
- {letschatty-0.4.343.dist-info → letschatty-0.4.344.dist-info}/METADATA +1 -1
- {letschatty-0.4.343.dist-info → letschatty-0.4.344.dist-info}/RECORD +11 -6
- {letschatty-0.4.343.dist-info → letschatty-0.4.344.dist-info}/LICENSE +0 -0
- {letschatty-0.4.343.dist-info → letschatty-0.4.344.dist-info}/WHEEL +0 -0
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
from .assets import *
|
|
2
2
|
from .empresa import EmpresaModel
|
|
3
3
|
from .form_field import FormField, FormFieldPreview, CollectedData, SystemFormFields
|
|
4
|
-
from .CRM.funnel import Funnel, FunnelPreview, ChatFunnel, StageTransition, FunnelStatus
|
|
4
|
+
from .CRM.funnel import Funnel, FunnelPreview, ChatFunnel, StageTransition, FunnelStatus
|
|
5
|
+
from .integrations.product_sync_status import ProductSyncStatus
|
|
6
|
+
from .integrations.sync_status_enum import SyncStatusEnum
|
|
7
|
+
from .integrations.shopify.shopify_webhook_topics import ShopifyWebhookTopic
|
|
8
|
+
from .integrations.shopify.company_shopify_integration import ShopifyIntegration
|
|
9
|
+
from .integrations.shopify.shopify_product_sync_status import ShopifyProductSyncStatus, ShopifyProductSyncStatusEnum
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from letschatty.models.company.integrations.shopify.company_shopify_integration import ShopifyIntegration
|
|
1
2
|
from pydantic import Field, ConfigDict, field_validator, SecretStr, model_validator
|
|
2
3
|
from typing import Optional, List, Dict
|
|
3
4
|
|
|
@@ -34,7 +35,7 @@ class EmpresaModel(ChattyAssetModel):
|
|
|
34
35
|
continuous_conversation_template_name: Optional[str] = Field(default = None, description="The name of the continuous conversation template")
|
|
35
36
|
default_follow_up_strategy_id: Optional[StrObjectId] = Field(default = None, description="The id of the default follow up strategy")
|
|
36
37
|
messaging_settings: MessagingSettings = Field(default = MessagingSettings(), description="The messaging settings for the company")
|
|
37
|
-
|
|
38
|
+
shopify_integration: ShopifyIntegration = Field(default = ShopifyIntegration(), description="The Shopify integration for the company")
|
|
38
39
|
|
|
39
40
|
model_config = ConfigDict(
|
|
40
41
|
validate_by_name=True,
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from datetime import datetime
|
|
4
|
+
from typing import ClassVar, Optional
|
|
5
|
+
|
|
6
|
+
from pydantic import Field
|
|
7
|
+
|
|
8
|
+
from letschatty.models.company.integrations.sync_status_enum import SyncStatusEnum
|
|
9
|
+
from letschatty.models.base_models import CompanyAssetModel
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class ProductSyncStatus(CompanyAssetModel):
|
|
13
|
+
"""Generic product sync status for any e-commerce integration."""
|
|
14
|
+
|
|
15
|
+
COLLECTION: ClassVar[str] = "product_sync_statuses"
|
|
16
|
+
|
|
17
|
+
integration_type: str = Field(
|
|
18
|
+
description="Integration type (shopify, tiendanube, etc.)"
|
|
19
|
+
)
|
|
20
|
+
status: SyncStatusEnum = Field(description="Current sync status")
|
|
21
|
+
|
|
22
|
+
products_created: int = Field(default=0)
|
|
23
|
+
products_updated: int = Field(default=0)
|
|
24
|
+
|
|
25
|
+
name: str = Field(default="")
|
|
26
|
+
|
|
27
|
+
finished_at: Optional[datetime] = Field(default=None)
|
|
28
|
+
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
from typing import List, Optional
|
|
2
|
+
from datetime import datetime
|
|
3
|
+
from zoneinfo import ZoneInfo
|
|
4
|
+
from pydantic import BaseModel, Field
|
|
5
|
+
|
|
6
|
+
class ShopifyWebhookSubscription(BaseModel):
|
|
7
|
+
"""Represents a single webhook subscription"""
|
|
8
|
+
topic: str = Field(description="Webhook topic (e.g., 'products/create')")
|
|
9
|
+
webhook_id: Optional[str] = Field(default=None, description="Shopify webhook ID")
|
|
10
|
+
subscribed_at: datetime = Field(default_factory=lambda: datetime.now(tz=ZoneInfo("UTC")))
|
|
11
|
+
is_active: bool = Field(default=True, description="Whether subscription is active")
|
|
12
|
+
|
|
13
|
+
class ShopifyIntegration(BaseModel):
|
|
14
|
+
"""Shopify integration for the company"""
|
|
15
|
+
shopify_store_url: str = Field(default="")
|
|
16
|
+
oauth_state: str = Field(default="")
|
|
17
|
+
oauth_state_at: datetime = Field(default_factory=lambda: datetime.now(tz=ZoneInfo("UTC")))
|
|
18
|
+
access_token: Optional[str] = Field(default=None)
|
|
19
|
+
connected_at: Optional[datetime] = Field(default=None)
|
|
20
|
+
scope: Optional[str] = Field(default=None)
|
|
21
|
+
|
|
22
|
+
# Webhook subscriptions
|
|
23
|
+
webhook_subscriptions: List[ShopifyWebhookSubscription] = Field(
|
|
24
|
+
default_factory=list,
|
|
25
|
+
description="List of active webhook subscriptions"
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
# Scheduled sync settings
|
|
29
|
+
product_sync_enabled: bool = Field(
|
|
30
|
+
default=False,
|
|
31
|
+
description="Whether scheduled product sync is enabled"
|
|
32
|
+
)
|
|
33
|
+
product_sync_interval_hours: int = Field(
|
|
34
|
+
default=24,
|
|
35
|
+
description="Interval in hours for scheduled product sync"
|
|
36
|
+
)
|
|
37
|
+
last_product_sync_at: Optional[datetime] = Field(
|
|
38
|
+
default=None,
|
|
39
|
+
description="Timestamp of last product sync"
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
@property
|
|
43
|
+
def is_connected(self) -> bool:
|
|
44
|
+
"""Check if the integration is fully connected"""
|
|
45
|
+
return bool(self.access_token and self.shopify_store_url)
|
|
46
|
+
|
|
47
|
+
def get_subscribed_topics(self) -> List[str]:
|
|
48
|
+
"""Get list of currently subscribed webhook topics"""
|
|
49
|
+
return [sub.topic for sub in self.webhook_subscriptions if sub.is_active]
|
|
50
|
+
|
|
51
|
+
def reset(self) -> None:
|
|
52
|
+
"""Reset integration to disconnected state"""
|
|
53
|
+
self.shopify_store_url = ""
|
|
54
|
+
self.oauth_state = ""
|
|
55
|
+
self.oauth_state_at = datetime.now(tz=ZoneInfo("UTC"))
|
|
56
|
+
self.access_token = None
|
|
57
|
+
self.connected_at = None
|
|
58
|
+
self.scope = None
|
|
59
|
+
self.webhook_subscriptions = []
|
|
60
|
+
self.product_sync_enabled = False
|
|
61
|
+
self.product_sync_interval_hours = 24
|
|
62
|
+
self.last_product_sync_at = None
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
from pydantic import Field
|
|
2
|
+
|
|
3
|
+
from letschatty.models.company.integrations.product_sync_status import ProductSyncStatus
|
|
4
|
+
from letschatty.models.company.integrations.sync_status_enum import SyncStatusEnum
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
# Backwards-compatible alias (Shopify-specific name, generic enum)
|
|
8
|
+
ShopifyProductSyncStatusEnum = SyncStatusEnum
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class ShopifyProductSyncStatus(ProductSyncStatus):
|
|
12
|
+
"""Shopify-flavored wrapper for the generic ProductSyncStatus."""
|
|
13
|
+
|
|
14
|
+
integration_type: str = Field(
|
|
15
|
+
default="shopify",
|
|
16
|
+
frozen=True,
|
|
17
|
+
description="Integration type for this sync status"
|
|
18
|
+
)
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
from enum import Enum
|
|
2
|
+
|
|
3
|
+
class ShopifyWebhookTopic(str, Enum):
|
|
4
|
+
"""Shopify webhook topics for products and orders"""
|
|
5
|
+
|
|
6
|
+
# Product webhooks
|
|
7
|
+
PRODUCTS_CREATE = "products/create"
|
|
8
|
+
PRODUCTS_UPDATE = "products/update"
|
|
9
|
+
PRODUCTS_DELETE = "products/delete"
|
|
10
|
+
|
|
11
|
+
# Order webhooks
|
|
12
|
+
ORDERS_CREATE = "orders/create"
|
|
13
|
+
ORDERS_UPDATE = "orders/updated"
|
|
14
|
+
ORDERS_DELETE = "orders/delete"
|
|
15
|
+
ORDERS_FULFILLED = "orders/fulfilled"
|
|
16
|
+
ORDERS_PARTIALLY_FULFILLED = "orders/partially_fulfilled"
|
|
17
|
+
ORDERS_PAID = "orders/paid"
|
|
18
|
+
ORDERS_CANCELLED = "orders/cancelled"
|
|
19
|
+
|
|
20
|
+
@classmethod
|
|
21
|
+
def get_product_topics(cls) -> list[str]:
|
|
22
|
+
"""Get all product-related webhook topics"""
|
|
23
|
+
return [
|
|
24
|
+
cls.PRODUCTS_CREATE.value,
|
|
25
|
+
cls.PRODUCTS_UPDATE.value,
|
|
26
|
+
cls.PRODUCTS_DELETE.value,
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
@classmethod
|
|
30
|
+
def get_order_topics(cls) -> list[str]:
|
|
31
|
+
"""Get all order-related webhook topics"""
|
|
32
|
+
return [
|
|
33
|
+
cls.ORDERS_CREATE.value,
|
|
34
|
+
cls.ORDERS_UPDATE.value,
|
|
35
|
+
cls.ORDERS_DELETE.value,
|
|
36
|
+
cls.ORDERS_FULFILLED.value,
|
|
37
|
+
cls.ORDERS_PARTIALLY_FULFILLED.value,
|
|
38
|
+
cls.ORDERS_PAID.value,
|
|
39
|
+
cls.ORDERS_CANCELLED.value,
|
|
40
|
+
]
|
|
@@ -78,7 +78,7 @@ letschatty/models/chat/temporary_chat.py,sha256=MR68vYrNvoyf40cLs2p5NnI8BNeN1VGT
|
|
|
78
78
|
letschatty/models/chat/time_left.py,sha256=2uA9dS_0QAVnWn7Q2wIwGe4tMrlYBP9qySC7M8I0jb8,3307
|
|
79
79
|
letschatty/models/company/CRM/business_area.py,sha256=U0F_7Rbq-e5tMSj_MugPqMHm2-IHxbAKbN0PWZ_93-o,296
|
|
80
80
|
letschatty/models/company/CRM/funnel.py,sha256=gBGZhud060sK5QFI5y9NgmFuhLCOAtzK81TKBhK2gxE,15820
|
|
81
|
-
letschatty/models/company/__init__.py,sha256=
|
|
81
|
+
letschatty/models/company/__init__.py,sha256=s6maWpREH-RAPoTm8svdivJ5foNEBkb5K6ncyZ0oEjo,626
|
|
82
82
|
letschatty/models/company/assets/__init__.py,sha256=z0xN_lt1D76bXt8DXVdbH3GkofUPQPZU9NioRSLt_lI,244
|
|
83
83
|
letschatty/models/company/assets/ai_agents_v2/ai_agent_message_draft.py,sha256=xbshA34RSjHm2g8J7hW2FkWo-Qm8MH2HTbcRcoYmyvc,2076
|
|
84
84
|
letschatty/models/company/assets/ai_agents_v2/ai_agents_decision_output.py,sha256=aEKZCOsGiFFPSx23fkS5Khfsxo-r8JGk3O0sxiGs8T0,5876
|
|
@@ -125,9 +125,14 @@ letschatty/models/company/assets/workflow_execution.py,sha256=CKlT9JTryKC8kNniRX
|
|
|
125
125
|
letschatty/models/company/company_chats_snapshot.py,sha256=Mg9Wmu3pfE-t5Sf57FCj-psvc5TkDkFfma-hdh6nE0Q,668
|
|
126
126
|
letschatty/models/company/company_messaging_settgins.py,sha256=7isXt7gmqw-FKSUSZwdctdXDFMfPi2OyPuWqB7WpC6c,957
|
|
127
127
|
letschatty/models/company/conversation_topic.py,sha256=__IinJ3YcUsiApF4Em5uAgd01ydRUrlCVxaat-pCCRg,1704
|
|
128
|
-
letschatty/models/company/empresa.py,sha256=
|
|
128
|
+
letschatty/models/company/empresa.py,sha256=o3IgQqMjQmyDjmR9je3bSF4EiIlJk7BnafiCO5c3pVE,6205
|
|
129
129
|
letschatty/models/company/form_field.py,sha256=LGyMLybwvfEPG3hMmwsoP_4wnMaPJbVFpG6c1HdVC8E,9802
|
|
130
130
|
letschatty/models/company/insight.py,sha256=B7BL07E4Z1b9aJHi3PXC1atln4-7fSo9JeqgQoeB_ao,7459
|
|
131
|
+
letschatty/models/company/integrations/product_sync_status.py,sha256=115zOvkaeXpHIUQftXe6dJsOUki3ru8hG3c75e2v4ag,814
|
|
132
|
+
letschatty/models/company/integrations/shopify/company_shopify_integration.py,sha256=PbxgIOG0Qp9Bz0WDrQffuSWrbEiV93JjX7PtHeYsqa0,2496
|
|
133
|
+
letschatty/models/company/integrations/shopify/shopify_product_sync_status.py,sha256=FhsmtFIf82pO9a1_OwV3MyKiJ6CGzlw-SCANZoV2M2g,588
|
|
134
|
+
letschatty/models/company/integrations/shopify/shopify_webhook_topics.py,sha256=HlSm0JHH6G3NPug8tbx9PQaC9yO3cwXJPTuU3qkWdDk,1263
|
|
135
|
+
letschatty/models/company/integrations/sync_status_enum.py,sha256=gh5kkKgLRqhygFFUPhITksp0Z-ImFEpGpzVABr7JiFM,154
|
|
131
136
|
letschatty/models/company/notifications/notification.py,sha256=wE7rIi21nZno6jjIxajMz4e7OJbzrDHjH1KdkNzJiF8,1907
|
|
132
137
|
letschatty/models/copilot/links.py,sha256=mcddNR6WdWOoOr3NgDl_FElxF15SiZZXw9wmIV08HRw,185
|
|
133
138
|
letschatty/models/data_base/__init__.py,sha256=cUTj-TBUYJn1iAofztCr3VUJFF9qg1vmaQlOuoKb1MM,45
|
|
@@ -275,7 +280,7 @@ letschatty/services/template_campaigns/template_campaign_service.py,sha256=jORgD
|
|
|
275
280
|
letschatty/services/users/agent_service.py,sha256=hIkUUJ1SpkKbh5_uo4i2CeqGtuMTjU7tSV8k5J7WPG4,279
|
|
276
281
|
letschatty/services/users/user_factory.py,sha256=FCB9uiAfjMeYfh4kMdx5h8VDHJ8MCsD-uaxW3X3KaWM,6681
|
|
277
282
|
letschatty/services/validators/analytics_validator.py,sha256=6ejecLcif2i1C5trUo1qQgp8vKr9WchdljFZ5GzB2i4,7239
|
|
278
|
-
letschatty-0.4.
|
|
279
|
-
letschatty-0.4.
|
|
280
|
-
letschatty-0.4.
|
|
281
|
-
letschatty-0.4.
|
|
283
|
+
letschatty-0.4.344.dist-info/LICENSE,sha256=EClLu_bO2HBLDcThowIwfaIg5EOwIYhpRsBJjVEk92A,1197
|
|
284
|
+
letschatty-0.4.344.dist-info/METADATA,sha256=0T1C22R5z3sxTuB3BCpuH5RAJBM81I4Ih0UWjKct3LY,3283
|
|
285
|
+
letschatty-0.4.344.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
|
|
286
|
+
letschatty-0.4.344.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|