chatgraph 1.2.4__tar.gz → 1.2.6__tar.gz

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.
Files changed (65) hide show
  1. {chatgraph-1.2.4 → chatgraph-1.2.6}/PKG-INFO +1 -1
  2. {chatgraph-1.2.4 → chatgraph-1.2.6}/chatgraph/__init__.py +4 -1
  3. {chatgraph-1.2.4 → chatgraph-1.2.6}/chatgraph/logger/__init__.py +11 -11
  4. {chatgraph-1.2.4 → chatgraph-1.2.6}/chatgraph/logger/user_logger.py +97 -88
  5. {chatgraph-1.2.4 → chatgraph-1.2.6}/chatgraph/messages/message_consumer.py +14 -4
  6. chatgraph-1.2.6/chatgraph/models/platform_state.py +35 -0
  7. {chatgraph-1.2.4 → chatgraph-1.2.6}/chatgraph/services/router_http_client.py +8 -3
  8. {chatgraph-1.2.4 → chatgraph-1.2.6}/chatgraph/types/usercall.py +29 -10
  9. {chatgraph-1.2.4 → chatgraph-1.2.6}/docs/gaps-go-to-python.md +150 -150
  10. {chatgraph-1.2.4 → chatgraph-1.2.6}/docs/gaps-python-to-go.md +65 -65
  11. {chatgraph-1.2.4 → chatgraph-1.2.6}/example2.py +59 -59
  12. {chatgraph-1.2.4 → chatgraph-1.2.6}/pyproject.toml +1 -1
  13. {chatgraph-1.2.4 → chatgraph-1.2.6}/tests/unit/test_default_guard.py +93 -92
  14. {chatgraph-1.2.4 → chatgraph-1.2.6}/tests/unit/test_message_consumer.py +403 -403
  15. chatgraph-1.2.6/tests/unit/test_models_platform_state.py +52 -0
  16. {chatgraph-1.2.4 → chatgraph-1.2.6}/tests/unit/test_router_http_client.py +105 -14
  17. {chatgraph-1.2.4 → chatgraph-1.2.6}/tests/unit/test_user_logger.py +146 -146
  18. {chatgraph-1.2.4 → chatgraph-1.2.6}/tests/unit/test_usercall.py +436 -400
  19. {chatgraph-1.2.4 → chatgraph-1.2.6}/.env.example +0 -0
  20. {chatgraph-1.2.4 → chatgraph-1.2.6}/.github/agents/SkillManager.agent.md +0 -0
  21. {chatgraph-1.2.4 → chatgraph-1.2.6}/.github/agents/architect.agent.md +0 -0
  22. {chatgraph-1.2.4 → chatgraph-1.2.6}/.github/agents/code-reviewer.agent.md +0 -0
  23. {chatgraph-1.2.4 → chatgraph-1.2.6}/.github/agents/developer.agent.md +0 -0
  24. {chatgraph-1.2.4 → chatgraph-1.2.6}/.github/copilot-instructions.md +0 -0
  25. {chatgraph-1.2.4 → chatgraph-1.2.6}/.github/skills/chatgraph-framework/SKILL.md +0 -0
  26. {chatgraph-1.2.4 → chatgraph-1.2.6}/.gitignore +0 -0
  27. {chatgraph-1.2.4 → chatgraph-1.2.6}/.python-version +0 -0
  28. {chatgraph-1.2.4 → chatgraph-1.2.6}/LICENSE +0 -0
  29. {chatgraph-1.2.4 → chatgraph-1.2.6}/README.md +0 -0
  30. {chatgraph-1.2.4 → chatgraph-1.2.6}/chatgraph/auth/credentials.py +0 -0
  31. {chatgraph-1.2.4 → chatgraph-1.2.6}/chatgraph/bot/chatbot_model.py +0 -0
  32. {chatgraph-1.2.4 → chatgraph-1.2.6}/chatgraph/bot/chatbot_router.py +0 -0
  33. {chatgraph-1.2.4 → chatgraph-1.2.6}/chatgraph/bot/default_functions.py +0 -0
  34. {chatgraph-1.2.4 → chatgraph-1.2.6}/chatgraph/bot/default_guard.py +0 -0
  35. {chatgraph-1.2.4 → chatgraph-1.2.6}/chatgraph/cli/__init__.py +0 -0
  36. {chatgraph-1.2.4 → chatgraph-1.2.6}/chatgraph/container/container.py +0 -0
  37. {chatgraph-1.2.4 → chatgraph-1.2.6}/chatgraph/error/chatbot_error.py +0 -0
  38. {chatgraph-1.2.4 → chatgraph-1.2.6}/chatgraph/error/route_error.py +0 -0
  39. {chatgraph-1.2.4 → chatgraph-1.2.6}/chatgraph/gRPC/gRPCCall.py +0 -0
  40. {chatgraph-1.2.4 → chatgraph-1.2.6}/chatgraph/logger/logger.py +0 -0
  41. {chatgraph-1.2.4 → chatgraph-1.2.6}/chatgraph/models/actions.py +0 -0
  42. {chatgraph-1.2.4 → chatgraph-1.2.6}/chatgraph/models/http_responses.py +0 -0
  43. {chatgraph-1.2.4 → chatgraph-1.2.6}/chatgraph/models/message.py +0 -0
  44. {chatgraph-1.2.4 → chatgraph-1.2.6}/chatgraph/models/userstate.py +0 -0
  45. {chatgraph-1.2.4 → chatgraph-1.2.6}/chatgraph/pb/router.proto +0 -0
  46. {chatgraph-1.2.4 → chatgraph-1.2.6}/chatgraph/pb/router_pb2.py +0 -0
  47. {chatgraph-1.2.4 → chatgraph-1.2.6}/chatgraph/pb/router_pb2_grpc.py +0 -0
  48. {chatgraph-1.2.4 → chatgraph-1.2.6}/chatgraph/services/__init__.py +0 -0
  49. {chatgraph-1.2.4 → chatgraph-1.2.6}/chatgraph/types/background_task.py +0 -0
  50. {chatgraph-1.2.4 → chatgraph-1.2.6}/chatgraph/types/end_types.py +0 -0
  51. {chatgraph-1.2.4 → chatgraph-1.2.6}/chatgraph/types/route.py +0 -0
  52. {chatgraph-1.2.4 → chatgraph-1.2.6}/example.py +0 -0
  53. {chatgraph-1.2.4 → chatgraph-1.2.6}/jsons/voll_return.json +0 -0
  54. {chatgraph-1.2.4 → chatgraph-1.2.6}/poetry.lock +0 -0
  55. {chatgraph-1.2.4 → chatgraph-1.2.6}/tests/__init__.py +0 -0
  56. {chatgraph-1.2.4 → chatgraph-1.2.6}/tests/integration/__init__.py +0 -0
  57. {chatgraph-1.2.4 → chatgraph-1.2.6}/tests/integration/conftest.py +0 -0
  58. {chatgraph-1.2.4 → chatgraph-1.2.6}/tests/integration/test_router_client_integration.py +0 -0
  59. {chatgraph-1.2.4 → chatgraph-1.2.6}/tests/unit/__init__.py +0 -0
  60. {chatgraph-1.2.4 → chatgraph-1.2.6}/tests/unit/conftest.py +0 -0
  61. {chatgraph-1.2.4 → chatgraph-1.2.6}/tests/unit/test_guard.py +0 -0
  62. {chatgraph-1.2.4 → chatgraph-1.2.6}/tests/unit/test_models_actions.py +0 -0
  63. {chatgraph-1.2.4 → chatgraph-1.2.6}/tests/unit/test_models_message.py +0 -0
  64. {chatgraph-1.2.4 → chatgraph-1.2.6}/tests/unit/test_models_userstate.py +0 -0
  65. {chatgraph-1.2.4 → chatgraph-1.2.6}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: chatgraph
3
- Version: 1.2.4
3
+ Version: 1.2.6
4
4
  Summary: A user-friendly chatbot library
5
5
  Project-URL: Homepage, https://github.com/irissonnlima/chatgraph
6
6
  Project-URL: Repository, https://github.com/irissonnlima/chatgraph
@@ -6,15 +6,16 @@ from .container.container import Container
6
6
  from .logger import logger, set_level
7
7
  from .messages.message_consumer import MessageConsumer
8
8
  from .models.message import Button, File, Message, SendType, TextMessage
9
+ from .models.platform_state import PlatformState, VollStateData
9
10
  from .models.userstate import (
10
11
  AuthLevel,
11
12
  ChatID,
12
13
  Menu,
14
+ User,
13
15
  UserData,
14
16
  UserIdentity,
15
17
  UserInternal,
16
18
  UserState,
17
- User,
18
19
  )
19
20
  from .types.background_task import BackgroundTask
20
21
  from .types.end_types import (
@@ -54,4 +55,6 @@ __all__ = [
54
55
  "BackgroundTask",
55
56
  "Container", "logger",
56
57
  "default_guard",
58
+ "PlatformState",
59
+ "VollStateData",
57
60
  ]
@@ -1,11 +1,11 @@
1
- import logging
2
-
3
- from .user_logger import UserLoggerManager
4
-
5
- logger_httpx = logging.getLogger('httpx')
6
- logger_httpx.setLevel(logging.ERROR)
7
-
8
- get_system_logger = UserLoggerManager.get_system_logger
9
- get_user_logger = UserLoggerManager.get_user_logger
10
- set_level = UserLoggerManager.set_level
11
- remove_user_logger = UserLoggerManager.remove_user_logger
1
+ import logging
2
+
3
+ from .user_logger import UserLoggerManager
4
+
5
+ logger_httpx = logging.getLogger('httpx')
6
+ logger_httpx.setLevel(logging.ERROR)
7
+
8
+ get_system_logger = UserLoggerManager.get_system_logger
9
+ get_user_logger = UserLoggerManager.get_user_logger
10
+ set_level = UserLoggerManager.set_level
11
+ remove_user_logger = UserLoggerManager.remove_user_logger
@@ -1,88 +1,97 @@
1
- import logging
2
- import os
3
- import sys
4
-
5
- LOG_DIR = "chatgraph_logs"
6
- LOG_FORMAT = "%(asctime)s | %(levelname)s | %(message)s | %(funcName)s | %(name)s"
7
-
8
- _ENV_LEVEL = os.getenv("CHATGRAPH_LOG_LEVEL", "").upper()
9
- _DEFAULT_LEVEL: int = getattr(logging, _ENV_LEVEL, logging.INFO)
10
-
11
-
12
- class UserLoggerManager:
13
- _loggers: dict[str, logging.Logger] = {}
14
- _level: int = _DEFAULT_LEVEL
15
-
16
- @classmethod
17
- def set_level(cls, level: int | str) -> None:
18
- if isinstance(level, str):
19
- numeric = getattr(logging, level.upper(), None)
20
- if numeric is None:
21
- raise ValueError(f"Nível de log inválido: '{level}'")
22
- level = numeric
23
- cls._level = level
24
- for logger in cls._loggers.values():
25
- logger.setLevel(level)
26
- for handler in logger.handlers:
27
- handler.setLevel(level)
28
-
29
- @classmethod
30
- def get_user_logger(cls, user_id: str, company_id: str) -> logging.Logger:
31
- key = f"{user_id}_{company_id}"
32
- if key in cls._loggers:
33
- return cls._loggers[key]
34
-
35
- os.makedirs(LOG_DIR, exist_ok=True)
36
-
37
- logger = logging.getLogger(key)
38
- logger.setLevel(cls._level)
39
-
40
- if not logger.handlers:
41
- handler = logging.FileHandler(
42
- os.path.join(LOG_DIR, f"{key}.log"), encoding="utf-8"
43
- )
44
- handler.setLevel(cls._level)
45
- handler.setFormatter(logging.Formatter(LOG_FORMAT))
46
- logger.addHandler(handler)
47
- stream_handler = logging.StreamHandler(sys.stdout)
48
- stream_handler.setLevel(cls._level)
49
- stream_handler.setFormatter(logging.Formatter(LOG_FORMAT))
50
- logger.addHandler(stream_handler)
51
-
52
- cls._loggers[key] = logger
53
- return logger
54
-
55
- @classmethod
56
- def remove_user_logger(cls, user_id: str, company_id: str) -> None:
57
- key = f"{user_id}_{company_id}"
58
- logger = cls._loggers.pop(key, None)
59
- if logger:
60
- for handler in logger.handlers[:]:
61
- handler.close()
62
- logger.removeHandler(handler)
63
-
64
- @classmethod
65
- def get_system_logger(cls) -> logging.Logger:
66
- key = "chatgraph.system"
67
- if key in cls._loggers:
68
- return cls._loggers[key]
69
-
70
- os.makedirs(LOG_DIR, exist_ok=True)
71
-
72
- logger = logging.getLogger(key)
73
- logger.setLevel(cls._level)
74
-
75
- if not logger.handlers:
76
- handler = logging.FileHandler(
77
- os.path.join(LOG_DIR, "system.log"), encoding="utf-8"
78
- )
79
- handler.setLevel(cls._level)
80
- handler.setFormatter(logging.Formatter(LOG_FORMAT))
81
- logger.addHandler(handler)
82
- stream_handler = logging.StreamHandler(sys.stdout)
83
- stream_handler.setLevel(cls._level)
84
- stream_handler.setFormatter(logging.Formatter(LOG_FORMAT))
85
- logger.addHandler(stream_handler)
86
-
87
- cls._loggers[key] = logger
88
- return logger
1
+ import logging
2
+ import os
3
+ import sys
4
+
5
+ LOG_DIR = "chatgraph_logs"
6
+ LOG_FORMAT = "%(asctime)s | %(levelname)s | %(message)s | %(funcName)s | %(name)s"
7
+
8
+ _ENV_LEVEL = os.getenv("CHATGRAPH_LOG_LEVEL", "").upper()
9
+ _DEFAULT_LEVEL: int = getattr(logging, _ENV_LEVEL, logging.INFO)
10
+
11
+
12
+ class ChatIDFilter(logging.Filter):
13
+ def filter(self, record: logging.LogRecord) -> bool:
14
+ chat_id = getattr(record, 'chat_id', None)
15
+ if chat_id:
16
+ record.msg = f'[ChatID: {chat_id}] - {record.msg}'
17
+ return True
18
+
19
+
20
+ class UserLoggerManager:
21
+ _loggers: dict[str, logging.Logger] = {}
22
+ _level: int = _DEFAULT_LEVEL
23
+
24
+ @classmethod
25
+ def set_level(cls, level: int | str) -> None:
26
+ if isinstance(level, str):
27
+ numeric = getattr(logging, level.upper(), None)
28
+ if numeric is None:
29
+ raise ValueError(f"Nível de log inválido: '{level}'")
30
+ level = numeric
31
+ cls._level = level
32
+ for logger in cls._loggers.values():
33
+ logger.setLevel(level)
34
+ for handler in logger.handlers:
35
+ handler.setLevel(level)
36
+
37
+ @classmethod
38
+ def get_user_logger(cls, user_id: str, company_id: str) -> logging.Logger:
39
+ key = f"{user_id}_{company_id}"
40
+ if key in cls._loggers:
41
+ return cls._loggers[key]
42
+
43
+ os.makedirs(LOG_DIR, exist_ok=True)
44
+
45
+ logger = logging.getLogger(key)
46
+ logger.setLevel(cls._level)
47
+
48
+ if not logger.handlers:
49
+ handler = logging.FileHandler(
50
+ os.path.join(LOG_DIR, f"{key}.log"), encoding="utf-8"
51
+ )
52
+ handler.setLevel(cls._level)
53
+ handler.setFormatter(logging.Formatter(LOG_FORMAT))
54
+ logger.addHandler(handler)
55
+ stream_handler = logging.StreamHandler(sys.stdout)
56
+ stream_handler.setLevel(cls._level)
57
+ stream_handler.setFormatter(logging.Formatter(LOG_FORMAT))
58
+ logger.addHandler(stream_handler)
59
+ logger.addFilter(ChatIDFilter())
60
+
61
+ cls._loggers[key] = logger
62
+ return logger
63
+
64
+ @classmethod
65
+ def remove_user_logger(cls, user_id: str, company_id: str) -> None:
66
+ key = f"{user_id}_{company_id}"
67
+ logger = cls._loggers.pop(key, None)
68
+ if logger:
69
+ for handler in logger.handlers[:]:
70
+ handler.close()
71
+ logger.removeHandler(handler)
72
+
73
+ @classmethod
74
+ def get_system_logger(cls) -> logging.Logger:
75
+ key = "chatgraph.system"
76
+ if key in cls._loggers:
77
+ return cls._loggers[key]
78
+
79
+ os.makedirs(LOG_DIR, exist_ok=True)
80
+
81
+ logger = logging.getLogger(key)
82
+ logger.setLevel(cls._level)
83
+
84
+ if not logger.handlers:
85
+ handler = logging.FileHandler(
86
+ os.path.join(LOG_DIR, "system.log"), encoding="utf-8"
87
+ )
88
+ handler.setLevel(cls._level)
89
+ handler.setFormatter(logging.Formatter(LOG_FORMAT))
90
+ logger.addHandler(handler)
91
+ stream_handler = logging.StreamHandler(sys.stdout)
92
+ stream_handler.setLevel(cls._level)
93
+ stream_handler.setFormatter(logging.Formatter(LOG_FORMAT))
94
+ logger.addHandler(stream_handler)
95
+
96
+ cls._loggers[key] = logger
97
+ return logger
@@ -13,6 +13,7 @@ from rich.text import Text
13
13
  from ..auth.credentials import Credential
14
14
  from ..logger.user_logger import UserLoggerManager
15
15
  from ..models.message import Message
16
+ from ..models.platform_state import PlatformState
16
17
  from ..models.userstate import UserState
17
18
  from ..services.router_http_client import RouterHTTPClient
18
19
  from ..types.usercall import UserCall
@@ -154,7 +155,9 @@ class MessageConsumer:
154
155
  channel = await connection.channel()
155
156
  await channel.set_qos(prefetch_count=self.__prefetch_count)
156
157
  queue = await self.__declare_queue(channel)
157
- _logger.info('[x] Server inicializado! Aguardando solicitações RPC')
158
+ _logger.info(
159
+ '[x] Server inicializado! Aguardando solicitações RPC'
160
+ )
158
161
  async for message in queue:
159
162
  async with message.process():
160
163
  await self.on_request(message.body, process_message)
@@ -188,12 +191,14 @@ class MessageConsumer:
188
191
  _logger.error(f'Erro ao processar mensagem: {e}')
189
192
  finally:
190
193
  if pure_message is not None:
191
- UserLoggerManager.remove_user_logger(pure_message.user_id, pure_message.company_id)
194
+ UserLoggerManager.remove_user_logger(
195
+ pure_message.user_id, pure_message.company_id
196
+ )
192
197
 
193
198
  async def __transform_message(self, message: dict) -> UserCall:
194
199
  user_state = message.get('user_state', {})
195
200
  message_data = message.get('message', {})
196
- observation = user_state.get('observation', "{}")
201
+ observation = user_state.get('observation', '{}')
197
202
 
198
203
  if isinstance(observation, str):
199
204
  observation = json.loads(observation)
@@ -201,13 +206,18 @@ class MessageConsumer:
201
206
  user_state_models = UserState.from_dict(user_state)
202
207
  message_models = Message.from_dict(message_data)
203
208
 
204
- # Reutilizar o mesmo cliente para todas as mensagens
209
+ platform_state_data = message.get('platform_state', {})
210
+ if not isinstance(platform_state_data, dict):
211
+ platform_state_data = None
212
+ platform_state = PlatformState.from_dict(platform_state_data)
213
+
205
214
  router_client = await self.__initialize_router()
206
215
 
207
216
  usercall = UserCall(
208
217
  user_state=user_state_models,
209
218
  message=message_models,
210
219
  router_client=router_client,
220
+ platform_state=platform_state,
211
221
  )
212
222
 
213
223
  return usercall
@@ -0,0 +1,35 @@
1
+ from dataclasses import dataclass, field
2
+ from typing import Optional
3
+
4
+
5
+ @dataclass
6
+ class PlatformState:
7
+ data: dict = field(default_factory=dict)
8
+
9
+ def to_dict(self) -> dict:
10
+ return self.data
11
+
12
+ @classmethod
13
+ def from_dict(cls, data: Optional[dict]) -> 'PlatformState':
14
+ if data is None:
15
+ return cls(data={})
16
+ return cls(data=data)
17
+
18
+ @property
19
+ def as_voll(self) -> Optional['VollStateData']:
20
+ try:
21
+ return VollStateData(**self.data)
22
+ except (TypeError, ValueError):
23
+ return None
24
+
25
+ def __bool__(self) -> bool:
26
+ return bool(self.data)
27
+
28
+
29
+ @dataclass
30
+ class VollStateData:
31
+ session_id: int
32
+ customer_id: str
33
+ platform: str
34
+ protocol: str
35
+ campaign: str
@@ -3,10 +3,11 @@ from typing import Any, Dict, Optional
3
3
  import httpx
4
4
 
5
5
  from ..logger.user_logger import UserLoggerManager
6
- from ..models.http_responses import RouterResponses
7
- from ..models.userstate import UserState, ChatID, Menu, User, UserIdentity
8
- from ..models.message import Message, File
9
6
  from ..models.actions import EndAction
7
+ from ..models.http_responses import RouterResponses
8
+ from ..models.message import File, Message
9
+ from ..models.platform_state import PlatformState
10
+ from ..models.userstate import ChatID, Menu, User, UserIdentity, UserState
10
11
 
11
12
  _logger = UserLoggerManager.get_system_logger()
12
13
 
@@ -258,6 +259,7 @@ class RouterHTTPClient:
258
259
  self,
259
260
  message_data: Message,
260
261
  user_state: UserState,
262
+ platform_state: PlatformState = PlatformState(),
261
263
  ) -> Any:
262
264
  """
263
265
  Envia uma mensagem de texto ao usuário.
@@ -267,6 +269,7 @@ class RouterHTTPClient:
267
269
  - chat_id: ID do chat (user_id, company_id)
268
270
  - type: Tipo da mensagem
269
271
  - detail: Conteúdo da mensagem
272
+ platform_state: Estado específico da plataforma (opcional).
270
273
 
271
274
  Returns:
272
275
  Objeto de resposta com atributo 'status' indicando sucesso/falha.
@@ -280,6 +283,8 @@ class RouterHTTPClient:
280
283
  'message': message_data.to_dict(),
281
284
  'user_state': user_state.to_dict(),
282
285
  }
286
+ if platform_state:
287
+ payload['platform_state'] = platform_state.to_dict()
283
288
  _logger.debug(f"[send_message] POST {endpoint}")
284
289
  response = await self._actions_client.post(
285
290
  endpoint,
@@ -1,5 +1,4 @@
1
1
  import asyncio
2
- import concurrent.futures
3
2
  import json
4
3
  import logging
5
4
  from typing import Optional
@@ -10,6 +9,7 @@ from chatgraph.models.message import (
10
9
  Message,
11
10
  MessageTypes,
12
11
  )
12
+ from chatgraph.models.platform_state import PlatformState
13
13
  from chatgraph.models.userstate import Menu, User, UserIdentity, UserState
14
14
  from chatgraph.services.router_http_client import RouterHTTPClient
15
15
 
@@ -33,16 +33,23 @@ class UserCall: # noqa: PLR0904
33
33
  user_state: UserState,
34
34
  message: Message,
35
35
  router_client: RouterHTTPClient,
36
+ platform_state: PlatformState = PlatformState(),
36
37
  ) -> None:
37
38
  self.type = type
38
39
  self.__message = message
39
40
  self.__user_state = user_state
40
41
  self.__router_client = router_client
42
+ self.__platform_state = platform_state
41
43
  self.__content_message = self.__message.text_message.detail
42
44
 
43
45
  @property
44
- def logger(self) -> logging.Logger:
45
- return UserLoggerManager.get_user_logger(self.user_id, self.company_id)
46
+ def logger(self) -> logging.LoggerAdapter:
47
+ base_logger = UserLoggerManager.get_user_logger(
48
+ self.user_id, self.company_id
49
+ )
50
+ return logging.LoggerAdapter(
51
+ base_logger, {'chat_id': str(self.__user_state.chat_id)}
52
+ )
46
53
 
47
54
  def __str__(self):
48
55
  return (
@@ -115,21 +122,23 @@ class UserCall: # noqa: PLR0904
115
122
 
116
123
  async def __send(self, message: Message) -> None:
117
124
  try:
118
- self.logger.debug(
125
+ self.logger.info(
119
126
  f'Enviando mensagem | user={self.user_id} | company={self.company_id} | tipo={message.type if hasattr(message, "type") else "N/A"}'
120
127
  )
121
128
  response = await self.__router_client.send_message(
122
- message, self.__user_state
129
+ message, self.__user_state, self.__platform_state
123
130
  )
124
131
 
125
132
  if response:
126
- self.logger.debug(
133
+ self.logger.info(
127
134
  f'Mensagem enviada com sucesso | user={self.user_id}'
128
135
  )
129
136
 
130
137
  await asyncio.sleep(0.1)
131
138
  except Exception as e:
132
- raise Exception(f'Erro ao enviar mensagem: {e}')
139
+ raise Exception(
140
+ f'[ChatID: {self.__user_state.chat_id}] - Erro ao enviar mensagem: {e}'
141
+ )
133
142
 
134
143
  async def send(
135
144
  self,
@@ -321,7 +330,9 @@ class UserCall: # noqa: PLR0904
321
330
  async def load_identity(self, cpf: Optional[str] = None) -> UserIdentity:
322
331
  try:
323
332
  self.logger.debug(f'Consultando identidade | user={self.user_id}')
324
- identity = await self.__router_client.get_identity(self.user_id, cpf=cpf)
333
+ identity = await self.__router_client.get_identity(
334
+ self.user_id, cpf=cpf
335
+ )
325
336
  if self.__user_state.user is None:
326
337
  self.__user_state.user = User()
327
338
  self.__user_state.user.identity = identity
@@ -336,9 +347,13 @@ class UserCall: # noqa: PLR0904
336
347
  async def load_userstate(self) -> UserState:
337
348
  try:
338
349
  self.logger.debug(f'Carregando userstate | user={self.user_id}')
339
- resultado = await self.__router_client.get_session_by_chat_id(self.__user_state.chat_id)
350
+ resultado = await self.__router_client.get_session_by_chat_id(
351
+ self.__user_state.chat_id
352
+ )
340
353
  if resultado is None:
341
- raise ValueError('Sessão não encontrada para o chat_id informado.')
354
+ raise ValueError(
355
+ 'Sessão não encontrada para o chat_id informado.'
356
+ )
342
357
  self.__user_state = resultado
343
358
  self.logger.info(
344
359
  f'Userstate carregado | user={self.user_id} | route={self.__user_state.route}'
@@ -400,6 +415,10 @@ class UserCall: # noqa: PLR0904
400
415
  def observation(self):
401
416
  return self.__user_state.observation_dict
402
417
 
418
+ @property
419
+ def platform_state(self) -> PlatformState:
420
+ return self.__platform_state
421
+
403
422
  @property
404
423
  def content_message(self):
405
424
  return self.__content_message