chatgraph 0.6.0__py3-none-any.whl → 0.6.2__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 chatgraph might be problematic. Click here for more details.
- chatgraph/__init__.py +2 -2
- chatgraph/bot/chatbot_model.py +32 -2
- chatgraph/bot/default_functions.py +24 -0
- chatgraph/gRPC/gRPCCall.py +57 -19
- chatgraph/pb/router.proto +12 -5
- chatgraph/pb/router_pb2.py +56 -58
- chatgraph/pb/router_pb2_grpc.py +47 -0
- chatgraph/types/end_types.py +17 -2
- chatgraph/types/image.py +63 -7
- chatgraph/types/request_types.py +42 -12
- chatgraph/types/route.py +17 -12
- {chatgraph-0.6.0.dist-info → chatgraph-0.6.2.dist-info}/METADATA +1 -1
- chatgraph-0.6.2.dist-info/RECORD +24 -0
- chatgraph-0.6.0.dist-info/RECORD +0 -23
- {chatgraph-0.6.0.dist-info → chatgraph-0.6.2.dist-info}/LICENSE +0 -0
- {chatgraph-0.6.0.dist-info → chatgraph-0.6.2.dist-info}/WHEEL +0 -0
- {chatgraph-0.6.0.dist-info → chatgraph-0.6.2.dist-info}/entry_points.txt +0 -0
chatgraph/__init__.py
CHANGED
|
@@ -12,7 +12,7 @@ from .types.end_types import (
|
|
|
12
12
|
from .types.message_types import Message, Button
|
|
13
13
|
from .types.route import Route
|
|
14
14
|
from .types.background_task import BackgroundTask
|
|
15
|
-
from .types.image import ImageData,
|
|
15
|
+
from .types.image import ImageData, ImageMessage
|
|
16
16
|
|
|
17
17
|
__all__ = [
|
|
18
18
|
"ChatbotApp",
|
|
@@ -32,5 +32,5 @@ __all__ = [
|
|
|
32
32
|
"Button",
|
|
33
33
|
"BackgroundTask",
|
|
34
34
|
"ImageData",
|
|
35
|
-
"
|
|
35
|
+
"ImageMessage",
|
|
36
36
|
]
|
chatgraph/bot/chatbot_model.py
CHANGED
|
@@ -2,6 +2,7 @@ import inspect
|
|
|
2
2
|
from functools import wraps
|
|
3
3
|
from logging import debug, error
|
|
4
4
|
import asyncio
|
|
5
|
+
import re
|
|
5
6
|
|
|
6
7
|
from ..error.chatbot_error import ChatbotMessageError
|
|
7
8
|
from ..messages.message_consumer import MessageConsumer
|
|
@@ -16,6 +17,11 @@ from ..types.end_types import (
|
|
|
16
17
|
from ..types.route import Route
|
|
17
18
|
from .chatbot_router import ChatbotRouter
|
|
18
19
|
from ..types.background_task import BackgroundTask
|
|
20
|
+
from .default_functions import voltar
|
|
21
|
+
|
|
22
|
+
DEFAULT_FUNCTION: dict[str, callable] = {
|
|
23
|
+
r"^\s*(voltar)\s*$": voltar,
|
|
24
|
+
}
|
|
19
25
|
|
|
20
26
|
|
|
21
27
|
class ChatbotApp:
|
|
@@ -23,16 +29,22 @@ class ChatbotApp:
|
|
|
23
29
|
Classe principal para a aplicação do chatbot, gerencia as rotas e a lógica de processamento de mensagens.
|
|
24
30
|
"""
|
|
25
31
|
|
|
26
|
-
def __init__(
|
|
32
|
+
def __init__(
|
|
33
|
+
self,
|
|
34
|
+
message_consumer: MessageConsumer = None,
|
|
35
|
+
default_functions: dict[str, callable] = DEFAULT_FUNCTION,
|
|
36
|
+
):
|
|
27
37
|
"""
|
|
28
38
|
Inicializa a classe ChatbotApp com um estado de usuário e um consumidor de mensagens.
|
|
29
39
|
|
|
30
40
|
Args:
|
|
31
41
|
message_consumer (MessageConsumer): O consumidor de mensagens que lida com a entrada de mensagens no sistema.
|
|
42
|
+
default_functions (dict[str, callable]): Dicionário de funções padrão que podem ser usadas antes das rotas.
|
|
32
43
|
"""
|
|
33
44
|
if not message_consumer:
|
|
34
45
|
message_consumer = MessageConsumer.load_dotenv()
|
|
35
46
|
|
|
47
|
+
self.default_functions = default_functions
|
|
36
48
|
self.__message_consumer = message_consumer
|
|
37
49
|
self.__routes = {}
|
|
38
50
|
|
|
@@ -106,7 +118,20 @@ class ChatbotApp:
|
|
|
106
118
|
route = userCall.route.lower()
|
|
107
119
|
route_handler = route.split(".")[-1]
|
|
108
120
|
|
|
109
|
-
|
|
121
|
+
matchDefault = False
|
|
122
|
+
|
|
123
|
+
for regex, func in self.default_functions.items():
|
|
124
|
+
if re.match(regex, userCall.content_message):
|
|
125
|
+
matchDefault = True
|
|
126
|
+
debug(f"Função padrão encontrada: {func.__name__} para a rota {route}")
|
|
127
|
+
handler = {
|
|
128
|
+
"function": func,
|
|
129
|
+
"params": {UserCall: "userCall", Route: "route"},
|
|
130
|
+
}
|
|
131
|
+
break
|
|
132
|
+
|
|
133
|
+
if not matchDefault:
|
|
134
|
+
handler = self.__routes.get(route_handler, None)
|
|
110
135
|
|
|
111
136
|
if not handler:
|
|
112
137
|
raise ChatbotMessageError(user_id, f"Rota não encontrada para {route}!")
|
|
@@ -127,6 +152,9 @@ class ChatbotApp:
|
|
|
127
152
|
loop = asyncio.get_running_loop()
|
|
128
153
|
userCall_response = await loop.run_in_executor(None, lambda: func(**kwargs))
|
|
129
154
|
|
|
155
|
+
if matchDefault:
|
|
156
|
+
userCall.content_message = ""
|
|
157
|
+
|
|
130
158
|
if isinstance(userCall_response, (list, tuple)):
|
|
131
159
|
for response in userCall_response:
|
|
132
160
|
await self.__process_func_response(response, userCall, route=route)
|
|
@@ -166,6 +194,7 @@ class ChatbotApp:
|
|
|
166
194
|
userCall.end_chat,
|
|
167
195
|
userCall_response.observations,
|
|
168
196
|
userCall_response.tabulation_id,
|
|
197
|
+
userCall_response.tabulation_name,
|
|
169
198
|
)
|
|
170
199
|
return
|
|
171
200
|
|
|
@@ -175,6 +204,7 @@ class ChatbotApp:
|
|
|
175
204
|
userCall.transfer_to_human,
|
|
176
205
|
userCall_response.observations,
|
|
177
206
|
userCall_response.campaign_id,
|
|
207
|
+
userCall_response.campaign_name,
|
|
178
208
|
)
|
|
179
209
|
return
|
|
180
210
|
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
from ..types.request_types import UserCall
|
|
2
|
+
from ..types.message_types import Message, Button
|
|
3
|
+
from ..types.end_types import (
|
|
4
|
+
RedirectResponse,
|
|
5
|
+
EndChatResponse,
|
|
6
|
+
TransferToHuman,
|
|
7
|
+
TransferToMenu,
|
|
8
|
+
)
|
|
9
|
+
from ..types.route import Route
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
async def voltar(route: Route, userCall: UserCall) -> tuple:
|
|
13
|
+
"""
|
|
14
|
+
Função para voltar à rota anterior.
|
|
15
|
+
Args:
|
|
16
|
+
route (Route): A rota atual do chatbot.
|
|
17
|
+
usercall (UserCall): O objeto UserCall associado à chamada do usuário.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
previous = route.get_previous()
|
|
21
|
+
userCall.console.print(
|
|
22
|
+
f"Voltando rota. ({route.current}) -> ({previous.current})", style="bold yellow"
|
|
23
|
+
)
|
|
24
|
+
return RedirectResponse(previous.current_node)
|
chatgraph/gRPC/gRPCCall.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import os
|
|
2
2
|
import grpc
|
|
3
3
|
import json
|
|
4
|
+
from rich.console import Console
|
|
4
5
|
|
|
5
6
|
import chatgraph.pb.router_pb2 as chatbot_pb2
|
|
6
7
|
import chatgraph.pb.router_pb2_grpc as chatbot_pb2_grpc
|
|
@@ -22,15 +23,22 @@ class RouterServiceClient:
|
|
|
22
23
|
self.transfer_stub = chatbot_pb2_grpc.TransferStub(self.channel)
|
|
23
24
|
self.end_chat_stub = chatbot_pb2_grpc.EndChatStub(self.channel)
|
|
24
25
|
|
|
26
|
+
self.console = Console()
|
|
27
|
+
|
|
25
28
|
def insert_update_user_state(self, user_state_data):
|
|
26
29
|
request = chatbot_pb2.UserState(**user_state_data)
|
|
27
30
|
try:
|
|
28
31
|
response = self.user_state_stub.InsertUpdateUserState(request)
|
|
29
32
|
if not response.status:
|
|
30
|
-
print(
|
|
33
|
+
self.console.print(
|
|
34
|
+
f"Erro ao chamar InsertUpdateUserState: {response.message}",
|
|
35
|
+
style="bold red",
|
|
36
|
+
)
|
|
31
37
|
return response
|
|
32
38
|
except grpc.RpcError as e:
|
|
33
|
-
print(
|
|
39
|
+
self.console.print(
|
|
40
|
+
f"Erro ao chamar InsertUpdateUserState: {e}", style="bold red"
|
|
41
|
+
)
|
|
34
42
|
return None
|
|
35
43
|
|
|
36
44
|
def delete_user_state(self, chat_id_data):
|
|
@@ -38,10 +46,12 @@ class RouterServiceClient:
|
|
|
38
46
|
try:
|
|
39
47
|
response = self.user_state_stub.DeleteUserState(request)
|
|
40
48
|
if not response.status:
|
|
41
|
-
print(
|
|
49
|
+
self.console.print(
|
|
50
|
+
f"Erro ao chamar SendMessage: {response.message}", style="bold red"
|
|
51
|
+
)
|
|
42
52
|
return response
|
|
43
53
|
except grpc.RpcError as e:
|
|
44
|
-
print(f"Erro ao chamar DeleteUserState: {e}")
|
|
54
|
+
self.console.print(f"Erro ao chamar DeleteUserState: {e}", style="bold red")
|
|
45
55
|
return None
|
|
46
56
|
|
|
47
57
|
def get_user_state(self, chat_id_data):
|
|
@@ -50,7 +60,7 @@ class RouterServiceClient:
|
|
|
50
60
|
response = self.user_state_stub.GetUserState(request)
|
|
51
61
|
return response
|
|
52
62
|
except grpc.RpcError as e:
|
|
53
|
-
print(f"Erro ao chamar GetUserState: {e}")
|
|
63
|
+
self.console.print(f"Erro ao chamar GetUserState: {e}", style="bold red")
|
|
54
64
|
return None
|
|
55
65
|
|
|
56
66
|
def send_message(self, message_data):
|
|
@@ -61,10 +71,12 @@ class RouterServiceClient:
|
|
|
61
71
|
try:
|
|
62
72
|
response = self.send_message_stub.SendMessage(request)
|
|
63
73
|
if not response.status:
|
|
64
|
-
print(
|
|
74
|
+
self.console.print(
|
|
75
|
+
f"Erro ao chamar SendMessage: {response.message}", style="bold red"
|
|
76
|
+
)
|
|
65
77
|
return response
|
|
66
78
|
except grpc.RpcError as e:
|
|
67
|
-
print(f"Erro ao chamar SendMessage: {e}")
|
|
79
|
+
self.console.print(f"Erro ao chamar SendMessage: {e}", style="bold red")
|
|
68
80
|
return None
|
|
69
81
|
|
|
70
82
|
def send_image(self, message_data):
|
|
@@ -74,11 +86,28 @@ class RouterServiceClient:
|
|
|
74
86
|
|
|
75
87
|
try:
|
|
76
88
|
response = self.send_message_stub.SendImage(request)
|
|
89
|
+
if not response.status and response.message != "arquivo não encontrado":
|
|
90
|
+
self.console.print(
|
|
91
|
+
f"Erro ao chamar SendImage: {response.message}", style="bold red"
|
|
92
|
+
)
|
|
93
|
+
elif response.message == "arquivo não encontrado":
|
|
94
|
+
print("Arquivo não encontrado, Carregando arquivo...")
|
|
95
|
+
return response
|
|
96
|
+
except grpc.RpcError as e:
|
|
97
|
+
self.console.print(f"Erro ao chamar SendImage: {e}", style="bold red")
|
|
98
|
+
return None
|
|
99
|
+
|
|
100
|
+
def upload_file(self, file_data):
|
|
101
|
+
request = chatbot_pb2.UploadFileRequest(**file_data)
|
|
102
|
+
try:
|
|
103
|
+
response = self.send_message_stub.UploadFile(request)
|
|
77
104
|
if not response.status:
|
|
78
|
-
print(
|
|
105
|
+
self.console.print(
|
|
106
|
+
f"Erro ao chamar UploadFile: {response.message}", style="bold red"
|
|
107
|
+
)
|
|
79
108
|
return response
|
|
80
109
|
except grpc.RpcError as e:
|
|
81
|
-
print(f"Erro ao chamar
|
|
110
|
+
self.console.print(f"Erro ao chamar UploadFile: {e}", style="bold red")
|
|
82
111
|
return None
|
|
83
112
|
|
|
84
113
|
def transfer_to_human(self, transfer_request_data):
|
|
@@ -86,10 +115,12 @@ class RouterServiceClient:
|
|
|
86
115
|
try:
|
|
87
116
|
response = self.transfer_stub.TransferToHuman(request)
|
|
88
117
|
if not response.status:
|
|
89
|
-
print(
|
|
118
|
+
self.console.print(
|
|
119
|
+
f"Erro ao chamar SendMessage: {response.message}", style="bold red"
|
|
120
|
+
)
|
|
90
121
|
return response
|
|
91
122
|
except grpc.RpcError as e:
|
|
92
|
-
print(f"Erro ao chamar TransferToHuman: {e}")
|
|
123
|
+
self.console.print(f"Erro ao chamar TransferToHuman: {e}", style="bold red")
|
|
93
124
|
return None
|
|
94
125
|
|
|
95
126
|
def transfer_to_menu(self, transfer_request_data):
|
|
@@ -97,10 +128,13 @@ class RouterServiceClient:
|
|
|
97
128
|
try:
|
|
98
129
|
response = self.transfer_stub.TransferToMenu(request)
|
|
99
130
|
if not response.status:
|
|
100
|
-
print(
|
|
131
|
+
self.console.print(
|
|
132
|
+
f"Erro ao chamar TransferToMenu: {response.message}",
|
|
133
|
+
style="bold red",
|
|
134
|
+
)
|
|
101
135
|
return response
|
|
102
136
|
except grpc.RpcError as e:
|
|
103
|
-
print(f"Erro ao chamar TransferToMenu: {e}")
|
|
137
|
+
self.console.print(f"Erro ao chamar TransferToMenu: {e}", style="bold red")
|
|
104
138
|
return None
|
|
105
139
|
|
|
106
140
|
def end_chat(self, end_chat_request_data):
|
|
@@ -108,10 +142,12 @@ class RouterServiceClient:
|
|
|
108
142
|
try:
|
|
109
143
|
response = self.end_chat_stub.EndChat(request)
|
|
110
144
|
if not response.status:
|
|
111
|
-
print(
|
|
145
|
+
self.console.print(
|
|
146
|
+
f"Erro ao chamar SendMessage: {response.message}", style="bold red"
|
|
147
|
+
)
|
|
112
148
|
return response
|
|
113
149
|
except grpc.RpcError as e:
|
|
114
|
-
print(f"Erro ao chamar EndChat: {e}")
|
|
150
|
+
self.console.print(f"Erro ao chamar EndChat: {e}", style="bold red")
|
|
115
151
|
return None
|
|
116
152
|
|
|
117
153
|
def get_campaign_id(self, campaign_name):
|
|
@@ -120,7 +156,7 @@ class RouterServiceClient:
|
|
|
120
156
|
response = self.transfer_stub.GetCampaignID(request)
|
|
121
157
|
return response
|
|
122
158
|
except grpc.RpcError as e:
|
|
123
|
-
print(f"Erro ao chamar GetCampaignID: {e}")
|
|
159
|
+
self.console.print(f"Erro ao chamar GetCampaignID: {e}", style="bold red")
|
|
124
160
|
return None
|
|
125
161
|
|
|
126
162
|
def get_all_campaigns(self):
|
|
@@ -129,7 +165,7 @@ class RouterServiceClient:
|
|
|
129
165
|
response = self.transfer_stub.GetAllCampaigns(request)
|
|
130
166
|
return response
|
|
131
167
|
except grpc.RpcError as e:
|
|
132
|
-
print(f"Erro ao chamar GetAllCampaigns: {e}")
|
|
168
|
+
self.console.print(f"Erro ao chamar GetAllCampaigns: {e}", style="bold red")
|
|
133
169
|
return None
|
|
134
170
|
|
|
135
171
|
def get_tabulation_id(self, tabulation_name):
|
|
@@ -138,7 +174,7 @@ class RouterServiceClient:
|
|
|
138
174
|
response = self.end_chat_stub.GetTabulationID(request)
|
|
139
175
|
return response
|
|
140
176
|
except grpc.RpcError as e:
|
|
141
|
-
print(f"Erro ao chamar GetTabulationID: {e}")
|
|
177
|
+
self.console.print(f"Erro ao chamar GetTabulationID: {e}", style="bold red")
|
|
142
178
|
return None
|
|
143
179
|
|
|
144
180
|
def get_all_tabulations(self):
|
|
@@ -147,5 +183,7 @@ class RouterServiceClient:
|
|
|
147
183
|
response = self.end_chat_stub.GetAllTabulations(request)
|
|
148
184
|
return response
|
|
149
185
|
except grpc.RpcError as e:
|
|
150
|
-
print(
|
|
186
|
+
self.console.print(
|
|
187
|
+
f"Erro ao chamar GetAllTabulations: {e}", style="bold red"
|
|
188
|
+
)
|
|
151
189
|
return None
|
chatgraph/pb/router.proto
CHANGED
|
@@ -7,6 +7,7 @@ option go_package = "./chatbot";
|
|
|
7
7
|
///// Serviços de Estado do Usuário /////
|
|
8
8
|
service UserStateService {
|
|
9
9
|
rpc InsertUpdateUserState(UserState) returns (RequestStatus);
|
|
10
|
+
rpc SetRoute(RouteRequest) returns (RequestStatus);
|
|
10
11
|
rpc DeleteUserState(ChatID) returns (RequestStatus);
|
|
11
12
|
rpc GetUserState(ChatID) returns (UserState);
|
|
12
13
|
rpc GetAllUserStates(Void) returns (UserStateList);
|
|
@@ -60,6 +61,10 @@ message UserStateList {
|
|
|
60
61
|
repeated UserState user_states = 1;
|
|
61
62
|
}
|
|
62
63
|
|
|
64
|
+
message RouteRequest {
|
|
65
|
+
ChatID chat_id = 1;
|
|
66
|
+
string route = 2;
|
|
67
|
+
}
|
|
63
68
|
///// Mensagens para Serviços de Mensagens /////
|
|
64
69
|
message TextMessage {
|
|
65
70
|
string type = 1;
|
|
@@ -89,10 +94,11 @@ message FileMessage {
|
|
|
89
94
|
}
|
|
90
95
|
|
|
91
96
|
message UploadFileRequest {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
97
|
+
string file_url = 1;
|
|
98
|
+
string file_type = 2;
|
|
99
|
+
string file_extension = 3;
|
|
100
|
+
string expiration = 4;
|
|
101
|
+
bytes file_content = 5;
|
|
96
102
|
}
|
|
97
103
|
|
|
98
104
|
///// Mensagens para Serviços de Transfer /////
|
|
@@ -105,7 +111,8 @@ message TransferToHumanRequest{
|
|
|
105
111
|
message TransferToMenuRequest{
|
|
106
112
|
ChatID chat_id = 1;
|
|
107
113
|
string menu = 2;
|
|
108
|
-
string
|
|
114
|
+
string route = 3;
|
|
115
|
+
string user_message = 4;
|
|
109
116
|
}
|
|
110
117
|
|
|
111
118
|
message TabulationName{
|
chatgraph/pb/router_pb2.py
CHANGED
|
@@ -9,73 +9,71 @@ from google.protobuf import descriptor_pool as _descriptor_pool
|
|
|
9
9
|
from google.protobuf import runtime_version as _runtime_version
|
|
10
10
|
from google.protobuf import symbol_database as _symbol_database
|
|
11
11
|
from google.protobuf.internal import builder as _builder
|
|
12
|
+
|
|
12
13
|
_runtime_version.ValidateProtobufRuntimeVersion(
|
|
13
|
-
_runtime_version.Domain.PUBLIC,
|
|
14
|
-
6,
|
|
15
|
-
31,
|
|
16
|
-
0,
|
|
17
|
-
'',
|
|
18
|
-
'router.proto'
|
|
14
|
+
_runtime_version.Domain.PUBLIC, 6, 31, 0, "", "router.proto"
|
|
19
15
|
)
|
|
20
16
|
# @@protoc_insertion_point(imports)
|
|
21
17
|
|
|
22
18
|
_sym_db = _symbol_database.Default()
|
|
23
19
|
|
|
24
20
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
21
|
+
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(
|
|
22
|
+
b'\n\x0crouter.proto\x12\x07\x63hatbot"\x06\n\x04Void"0\n\rRequestStatus\x12\x0e\n\x06status\x18\x01 \x01(\x08\x12\x0f\n\x07message\x18\x02 \x01(\t"-\n\x06\x43hatID\x12\x0f\n\x07user_id\x18\x01 \x01(\t\x12\x12\n\ncompany_id\x18\x02 \x01(\t"q\n\tUserState\x12 \n\x07\x63hat_id\x18\x01 \x01(\x0b\x32\x0f.chatbot.ChatID\x12\x0c\n\x04menu\x18\x02 \x01(\t\x12\r\n\x05route\x18\x03 \x01(\t\x12\x10\n\x08protocol\x18\x04 \x01(\t\x12\x13\n\x0bobservation\x18\x05 \x01(\t"8\n\rUserStateList\x12\'\n\x0buser_states\x18\x01 \x03(\x0b\x32\x12.chatbot.UserState"?\n\x0cRouteRequest\x12 \n\x07\x63hat_id\x18\x01 \x01(\x0b\x32\x0f.chatbot.ChatID\x12\r\n\x05route\x18\x02 \x01(\t"j\n\x0bTextMessage\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x0b\n\x03url\x18\x02 \x01(\t\x12\x10\n\x08\x66ilename\x18\x03 \x01(\t\x12\r\n\x05title\x18\x04 \x01(\t\x12\x0e\n\x06\x64\x65tail\x18\x05 \x01(\t\x12\x0f\n\x07\x63\x61ption\x18\x06 \x01(\t"5\n\x06\x42utton\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\r\n\x05title\x18\x02 \x01(\t\x12\x0e\n\x06\x64\x65tail\x18\x03 \x01(\t"\x9d\x01\n\x07Message\x12 \n\x07\x63hat_id\x18\x01 \x01(\x0b\x32\x0f.chatbot.ChatID\x12%\n\x07message\x18\x02 \x01(\x0b\x32\x14.chatbot.TextMessage\x12 \n\x07\x62uttons\x18\x03 \x03(\x0b\x32\x0f.chatbot.Button\x12\'\n\x0e\x64isplay_button\x18\x04 \x01(\x0b\x32\x0f.chatbot.Button"A\n\x0b\x46ileMessage\x12!\n\x07message\x18\x01 \x01(\x0b\x32\x10.chatbot.Message\x12\x0f\n\x07\x66ile_id\x18\x02 \x01(\t"z\n\x11UploadFileRequest\x12\x10\n\x08\x66ile_url\x18\x01 \x01(\t\x12\x11\n\tfile_type\x18\x02 \x01(\t\x12\x16\n\x0e\x66ile_extension\x18\x03 \x01(\t\x12\x12\n\nexpiration\x18\x04 \x01(\t\x12\x14\n\x0c\x66ile_content\x18\x05 \x01(\x0c"d\n\x16TransferToHumanRequest\x12 \n\x07\x63hat_id\x18\x01 \x01(\x0b\x32\x0f.chatbot.ChatID\x12\x13\n\x0b\x63\x61mpaign_id\x18\x02 \x01(\t\x12\x13\n\x0bobservation\x18\x03 \x01(\t"l\n\x15TransferToMenuRequest\x12 \n\x07\x63hat_id\x18\x01 \x01(\x0b\x32\x0f.chatbot.ChatID\x12\x0c\n\x04menu\x18\x02 \x01(\t\x12\r\n\x05route\x18\x03 \x01(\t\x12\x14\n\x0cuser_message\x18\x04 \x01(\t"\x1e\n\x0eTabulationName\x12\x0c\n\x04name\x18\x01 \x01(\t"B\n\x11TabulationDetails\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x13\n\x0blast_update\x18\x03 \x01(\t"B\n\x0fTabulationsList\x12/\n\x0btabulations\x18\x01 \x03(\x0b\x32\x1a.chatbot.TabulationDetails"^\n\x0e\x45ndChatRequest\x12 \n\x07\x63hat_id\x18\x01 \x01(\x0b\x32\x0f.chatbot.ChatID\x12\x15\n\rtabulation_id\x18\x02 \x01(\t\x12\x13\n\x0bobservation\x18\x03 \x01(\t"\x1c\n\x0c\x43\x61mpaignName\x12\x0c\n\x04name\x18\x01 \x01(\t"@\n\x0f\x43\x61mpaignDetails\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x13\n\x0blast_update\x18\x03 \x01(\t"<\n\rCampaignsList\x12+\n\tcampaigns\x18\x01 \x03(\x0b\x32\x18.chatbot.CampaignDetails2\xbe\x02\n\x10UserStateService\x12\x43\n\x15InsertUpdateUserState\x12\x12.chatbot.UserState\x1a\x16.chatbot.RequestStatus\x12\x39\n\x08SetRoute\x12\x15.chatbot.RouteRequest\x1a\x16.chatbot.RequestStatus\x12:\n\x0f\x44\x65leteUserState\x12\x0f.chatbot.ChatID\x1a\x16.chatbot.RequestStatus\x12\x33\n\x0cGetUserState\x12\x0f.chatbot.ChatID\x1a\x12.chatbot.UserState\x12\x39\n\x10GetAllUserStates\x12\r.chatbot.Void\x1a\x16.chatbot.UserStateList2\xfd\x01\n\x0bSendMessage\x12\x37\n\x0bSendMessage\x12\x10.chatbot.Message\x1a\x16.chatbot.RequestStatus\x12\x39\n\tSendImage\x12\x14.chatbot.FileMessage\x1a\x16.chatbot.RequestStatus\x12\x38\n\x08SendFile\x12\x14.chatbot.FileMessage\x1a\x16.chatbot.RequestStatus\x12@\n\nUploadFile\x12\x1a.chatbot.UploadFileRequest\x1a\x16.chatbot.RequestStatus2\x9c\x02\n\x08Transfer\x12\x38\n\x0fGetAllCampaigns\x12\r.chatbot.Void\x1a\x16.chatbot.CampaignsList\x12@\n\rGetCampaignID\x12\x15.chatbot.CampaignName\x1a\x18.chatbot.CampaignDetails\x12J\n\x0fTransferToHuman\x12\x1f.chatbot.TransferToHumanRequest\x1a\x16.chatbot.RequestStatus\x12H\n\x0eTransferToMenu\x12\x1e.chatbot.TransferToMenuRequest\x1a\x16.chatbot.RequestStatus2\xcb\x01\n\x07\x45ndChat\x12<\n\x11GetAllTabulations\x12\r.chatbot.Void\x1a\x18.chatbot.TabulationsList\x12\x46\n\x0fGetTabulationID\x12\x17.chatbot.TabulationName\x1a\x1a.chatbot.TabulationDetails\x12:\n\x07\x45ndChat\x12\x17.chatbot.EndChatRequest\x1a\x16.chatbot.RequestStatusB\x0bZ\t./chatbotb\x06proto3'
|
|
23
|
+
)
|
|
28
24
|
|
|
29
25
|
_globals = globals()
|
|
30
26
|
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
|
31
|
-
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR,
|
|
27
|
+
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "router_pb2", _globals)
|
|
32
28
|
if not _descriptor._USE_C_DESCRIPTORS:
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
29
|
+
_globals["DESCRIPTOR"]._loaded_options = None
|
|
30
|
+
_globals["DESCRIPTOR"]._serialized_options = b"Z\t./chatbot"
|
|
31
|
+
_globals["_VOID"]._serialized_start = 25
|
|
32
|
+
_globals["_VOID"]._serialized_end = 31
|
|
33
|
+
_globals["_REQUESTSTATUS"]._serialized_start = 33
|
|
34
|
+
_globals["_REQUESTSTATUS"]._serialized_end = 81
|
|
35
|
+
_globals["_CHATID"]._serialized_start = 83
|
|
36
|
+
_globals["_CHATID"]._serialized_end = 128
|
|
37
|
+
_globals["_USERSTATE"]._serialized_start = 130
|
|
38
|
+
_globals["_USERSTATE"]._serialized_end = 243
|
|
39
|
+
_globals["_USERSTATELIST"]._serialized_start = 245
|
|
40
|
+
_globals["_USERSTATELIST"]._serialized_end = 301
|
|
41
|
+
_globals["_ROUTEREQUEST"]._serialized_start = 303
|
|
42
|
+
_globals["_ROUTEREQUEST"]._serialized_end = 366
|
|
43
|
+
_globals["_TEXTMESSAGE"]._serialized_start = 368
|
|
44
|
+
_globals["_TEXTMESSAGE"]._serialized_end = 474
|
|
45
|
+
_globals["_BUTTON"]._serialized_start = 476
|
|
46
|
+
_globals["_BUTTON"]._serialized_end = 529
|
|
47
|
+
_globals["_MESSAGE"]._serialized_start = 532
|
|
48
|
+
_globals["_MESSAGE"]._serialized_end = 689
|
|
49
|
+
_globals["_FILEMESSAGE"]._serialized_start = 691
|
|
50
|
+
_globals["_FILEMESSAGE"]._serialized_end = 756
|
|
51
|
+
_globals["_UPLOADFILEREQUEST"]._serialized_start = 758
|
|
52
|
+
_globals["_UPLOADFILEREQUEST"]._serialized_end = 880
|
|
53
|
+
_globals["_TRANSFERTOHUMANREQUEST"]._serialized_start = 882
|
|
54
|
+
_globals["_TRANSFERTOHUMANREQUEST"]._serialized_end = 982
|
|
55
|
+
_globals["_TRANSFERTOMENUREQUEST"]._serialized_start = 984
|
|
56
|
+
_globals["_TRANSFERTOMENUREQUEST"]._serialized_end = 1092
|
|
57
|
+
_globals["_TABULATIONNAME"]._serialized_start = 1094
|
|
58
|
+
_globals["_TABULATIONNAME"]._serialized_end = 1124
|
|
59
|
+
_globals["_TABULATIONDETAILS"]._serialized_start = 1126
|
|
60
|
+
_globals["_TABULATIONDETAILS"]._serialized_end = 1192
|
|
61
|
+
_globals["_TABULATIONSLIST"]._serialized_start = 1194
|
|
62
|
+
_globals["_TABULATIONSLIST"]._serialized_end = 1260
|
|
63
|
+
_globals["_ENDCHATREQUEST"]._serialized_start = 1262
|
|
64
|
+
_globals["_ENDCHATREQUEST"]._serialized_end = 1356
|
|
65
|
+
_globals["_CAMPAIGNNAME"]._serialized_start = 1358
|
|
66
|
+
_globals["_CAMPAIGNNAME"]._serialized_end = 1386
|
|
67
|
+
_globals["_CAMPAIGNDETAILS"]._serialized_start = 1388
|
|
68
|
+
_globals["_CAMPAIGNDETAILS"]._serialized_end = 1452
|
|
69
|
+
_globals["_CAMPAIGNSLIST"]._serialized_start = 1454
|
|
70
|
+
_globals["_CAMPAIGNSLIST"]._serialized_end = 1514
|
|
71
|
+
_globals["_USERSTATESERVICE"]._serialized_start = 1517
|
|
72
|
+
_globals["_USERSTATESERVICE"]._serialized_end = 1835
|
|
73
|
+
_globals["_SENDMESSAGE"]._serialized_start = 1838
|
|
74
|
+
_globals["_SENDMESSAGE"]._serialized_end = 2091
|
|
75
|
+
_globals["_TRANSFER"]._serialized_start = 2094
|
|
76
|
+
_globals["_TRANSFER"]._serialized_end = 2378
|
|
77
|
+
_globals["_ENDCHAT"]._serialized_start = 2381
|
|
78
|
+
_globals["_ENDCHAT"]._serialized_end = 2584
|
|
81
79
|
# @@protoc_insertion_point(module_scope)
|
chatgraph/pb/router_pb2_grpc.py
CHANGED
|
@@ -43,6 +43,12 @@ class UserStateServiceStub(object):
|
|
|
43
43
|
response_deserializer=router__pb2.RequestStatus.FromString,
|
|
44
44
|
_registered_method=True,
|
|
45
45
|
)
|
|
46
|
+
self.SetRoute = channel.unary_unary(
|
|
47
|
+
"/chatbot.UserStateService/SetRoute",
|
|
48
|
+
request_serializer=router__pb2.RouteRequest.SerializeToString,
|
|
49
|
+
response_deserializer=router__pb2.RequestStatus.FromString,
|
|
50
|
+
_registered_method=True,
|
|
51
|
+
)
|
|
46
52
|
self.DeleteUserState = channel.unary_unary(
|
|
47
53
|
"/chatbot.UserStateService/DeleteUserState",
|
|
48
54
|
request_serializer=router__pb2.ChatID.SerializeToString,
|
|
@@ -72,6 +78,12 @@ class UserStateServiceServicer(object):
|
|
|
72
78
|
context.set_details("Method not implemented!")
|
|
73
79
|
raise NotImplementedError("Method not implemented!")
|
|
74
80
|
|
|
81
|
+
def SetRoute(self, request, context):
|
|
82
|
+
"""Missing associated documentation comment in .proto file."""
|
|
83
|
+
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
|
84
|
+
context.set_details("Method not implemented!")
|
|
85
|
+
raise NotImplementedError("Method not implemented!")
|
|
86
|
+
|
|
75
87
|
def DeleteUserState(self, request, context):
|
|
76
88
|
"""Missing associated documentation comment in .proto file."""
|
|
77
89
|
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
|
@@ -98,6 +110,11 @@ def add_UserStateServiceServicer_to_server(servicer, server):
|
|
|
98
110
|
request_deserializer=router__pb2.UserState.FromString,
|
|
99
111
|
response_serializer=router__pb2.RequestStatus.SerializeToString,
|
|
100
112
|
),
|
|
113
|
+
"SetRoute": grpc.unary_unary_rpc_method_handler(
|
|
114
|
+
servicer.SetRoute,
|
|
115
|
+
request_deserializer=router__pb2.RouteRequest.FromString,
|
|
116
|
+
response_serializer=router__pb2.RequestStatus.SerializeToString,
|
|
117
|
+
),
|
|
101
118
|
"DeleteUserState": grpc.unary_unary_rpc_method_handler(
|
|
102
119
|
servicer.DeleteUserState,
|
|
103
120
|
request_deserializer=router__pb2.ChatID.FromString,
|
|
@@ -157,6 +174,36 @@ class UserStateService(object):
|
|
|
157
174
|
_registered_method=True,
|
|
158
175
|
)
|
|
159
176
|
|
|
177
|
+
@staticmethod
|
|
178
|
+
def SetRoute(
|
|
179
|
+
request,
|
|
180
|
+
target,
|
|
181
|
+
options=(),
|
|
182
|
+
channel_credentials=None,
|
|
183
|
+
call_credentials=None,
|
|
184
|
+
insecure=False,
|
|
185
|
+
compression=None,
|
|
186
|
+
wait_for_ready=None,
|
|
187
|
+
timeout=None,
|
|
188
|
+
metadata=None,
|
|
189
|
+
):
|
|
190
|
+
return grpc.experimental.unary_unary(
|
|
191
|
+
request,
|
|
192
|
+
target,
|
|
193
|
+
"/chatbot.UserStateService/SetRoute",
|
|
194
|
+
router__pb2.RouteRequest.SerializeToString,
|
|
195
|
+
router__pb2.RequestStatus.FromString,
|
|
196
|
+
options,
|
|
197
|
+
channel_credentials,
|
|
198
|
+
insecure,
|
|
199
|
+
call_credentials,
|
|
200
|
+
compression,
|
|
201
|
+
wait_for_ready,
|
|
202
|
+
timeout,
|
|
203
|
+
metadata,
|
|
204
|
+
_registered_method=True,
|
|
205
|
+
)
|
|
206
|
+
|
|
160
207
|
@staticmethod
|
|
161
208
|
def DeleteUserState(
|
|
162
209
|
request,
|
chatgraph/types/end_types.py
CHANGED
|
@@ -25,11 +25,20 @@ class EndChatResponse:
|
|
|
25
25
|
observations (str): As observações finais do chatbot.
|
|
26
26
|
"""
|
|
27
27
|
|
|
28
|
-
def __init__(
|
|
28
|
+
def __init__(
|
|
29
|
+
self,
|
|
30
|
+
tabulation_id: str,
|
|
31
|
+
tabulation_name: str | None = None,
|
|
32
|
+
observations: str | None = None,
|
|
33
|
+
) -> None:
|
|
29
34
|
"""
|
|
30
35
|
Finzaliza e tabula as informações do chatbot.
|
|
31
36
|
"""
|
|
37
|
+
if not tabulation_id and not tabulation_name:
|
|
38
|
+
raise ValueError("tabulation_id or tabulation_name must be provided.")
|
|
39
|
+
|
|
32
40
|
self.tabulation_id = tabulation_id
|
|
41
|
+
self.tabulation_name = tabulation_name
|
|
33
42
|
self.observations = observations
|
|
34
43
|
|
|
35
44
|
|
|
@@ -38,11 +47,17 @@ class TransferToHuman:
|
|
|
38
47
|
Representa uma transferencia para um atendente humano.
|
|
39
48
|
"""
|
|
40
49
|
|
|
41
|
-
def __init__(
|
|
50
|
+
def __init__(
|
|
51
|
+
self,
|
|
52
|
+
campaign_id: str,
|
|
53
|
+
campaign_name: str | None = None,
|
|
54
|
+
observations: str | None = None,
|
|
55
|
+
) -> None:
|
|
42
56
|
"""
|
|
43
57
|
Finzaliza e tabula as informações do chatbot.
|
|
44
58
|
"""
|
|
45
59
|
self.campaign_id = campaign_id
|
|
60
|
+
self.campaign_name = campaign_name
|
|
46
61
|
self.observations = observations
|
|
47
62
|
|
|
48
63
|
|
chatgraph/types/image.py
CHANGED
|
@@ -1,27 +1,77 @@
|
|
|
1
|
+
from datetime import datetime, timedelta
|
|
1
2
|
import hashlib
|
|
2
3
|
import base64
|
|
3
4
|
from chatgraph.types.message_types import Message
|
|
4
5
|
|
|
5
6
|
|
|
6
7
|
class ImageData:
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
"""
|
|
9
|
+
Representa dados de uma imagem, seja por URL ou arquivo local. Caso fornecido um url e um caminho de arquivo, o url será utilizado.
|
|
10
|
+
Atributos:
|
|
11
|
+
type (str): Tipo de imagem, "link" para URL ou "file" para arquivo local.
|
|
12
|
+
url (str): URL da imagem, se aplicável.
|
|
13
|
+
image_path (str): Caminho do arquivo de imagem, se aplicável.
|
|
14
|
+
expiration (int): Tempo de expiração em minutos, 0 para sem expiração.
|
|
15
|
+
"""
|
|
10
16
|
|
|
17
|
+
def __init__(self, *, url: str = None, image_path: str = None, expiration: int = 0):
|
|
18
|
+
|
|
19
|
+
if not url and not image_path:
|
|
20
|
+
raise ValueError("URL or image path must be provided.")
|
|
21
|
+
|
|
22
|
+
self.type = "link" if url else "file"
|
|
11
23
|
self.url = url
|
|
12
|
-
self.
|
|
24
|
+
self.expiration = expiration
|
|
25
|
+
|
|
26
|
+
self.image_bytes = None
|
|
27
|
+
self.file_extension = None
|
|
28
|
+
if self.type == "file":
|
|
29
|
+
if not image_path:
|
|
30
|
+
raise ValueError("Image path must be provided for file type.")
|
|
31
|
+
self.file_extension = image_path.split(".")[-1]
|
|
32
|
+
with open(image_path, "rb") as f:
|
|
33
|
+
self.image_bytes = f.read()
|
|
13
34
|
|
|
14
35
|
# Create hash of image bytes if available, otherwise use URL
|
|
15
|
-
hash_input = image_bytes if image_bytes else url.encode("utf-8")
|
|
36
|
+
hash_input = self.image_bytes if self.image_bytes else url.encode("utf-8")
|
|
16
37
|
|
|
17
38
|
# Create SHA-256 hash and encode in base64
|
|
18
39
|
self.image_id = base64.b64encode(hashlib.sha256(hash_input).digest()).decode(
|
|
19
40
|
"utf-8"
|
|
20
41
|
)
|
|
21
42
|
|
|
43
|
+
def get_upload_dict(self):
|
|
44
|
+
dict_data = {}
|
|
45
|
+
if self.expiration > 0:
|
|
46
|
+
now = datetime.now()
|
|
47
|
+
expiration_time = now + timedelta(minutes=self.expiration)
|
|
48
|
+
dict_data["expiration"] = expiration_time.strftime("%Y-%m-%d %H:%M:%S")
|
|
49
|
+
|
|
50
|
+
if self.type == "file":
|
|
51
|
+
dict_data["file_type"] = self.type
|
|
52
|
+
dict_data["file_content"] = self.image_bytes
|
|
53
|
+
dict_data["file_extension"] = self.file_extension
|
|
54
|
+
else:
|
|
55
|
+
dict_data["file_type"] = self.type
|
|
56
|
+
dict_data["file_url"] = self.url
|
|
57
|
+
|
|
58
|
+
return dict_data
|
|
22
59
|
|
|
23
|
-
|
|
24
|
-
|
|
60
|
+
def get_dict(self):
|
|
61
|
+
dict_data = {
|
|
62
|
+
"image_id": self.image_id,
|
|
63
|
+
"file_type": self.type,
|
|
64
|
+
}
|
|
65
|
+
if self.type == "file":
|
|
66
|
+
dict_data["file_content"] = self.image_bytes
|
|
67
|
+
dict_data["file_extension"] = self.file_extension
|
|
68
|
+
else:
|
|
69
|
+
dict_data["file_url"] = self.url
|
|
70
|
+
return dict_data
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class ImageMessage:
|
|
74
|
+
def __init__(self, image: ImageData, message: Message = None):
|
|
25
75
|
if not isinstance(image, ImageData):
|
|
26
76
|
raise TypeError("Expected an instance of ImageData.")
|
|
27
77
|
|
|
@@ -30,6 +80,12 @@ class SendImage:
|
|
|
30
80
|
self.message = message
|
|
31
81
|
|
|
32
82
|
def to_dict(self):
|
|
83
|
+
if not self.message:
|
|
84
|
+
return {
|
|
85
|
+
"file_id": self.image.image_id,
|
|
86
|
+
"message": {},
|
|
87
|
+
}
|
|
88
|
+
|
|
33
89
|
return {
|
|
34
90
|
"file_id": self.image.image_id,
|
|
35
91
|
"message": self.message.to_dict(),
|
chatgraph/types/request_types.py
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
from chatgraph.gRPC.gRPCCall import RouterServiceClient
|
|
2
|
-
from chatgraph.types.image import ImageData,
|
|
2
|
+
from chatgraph.types.image import ImageData, ImageMessage
|
|
3
3
|
from chatgraph.types.message_types import Message, Button, MessageTypes, messageTypes
|
|
4
4
|
from typing import Optional
|
|
5
5
|
from datetime import datetime
|
|
6
6
|
import json, os
|
|
7
|
+
from rich.console import Console
|
|
7
8
|
|
|
8
9
|
|
|
9
10
|
class ChatID:
|
|
@@ -155,6 +156,7 @@ class UserCall:
|
|
|
155
156
|
self.__grpc_uri = grpc_uri
|
|
156
157
|
|
|
157
158
|
self.__router_client = RouterServiceClient(self.__grpc_uri)
|
|
159
|
+
self.console = Console()
|
|
158
160
|
|
|
159
161
|
def __str__(self):
|
|
160
162
|
return f"UserCall({self.type}, {self.__type_message}, {self.__content_message}, {self.__user_state})"
|
|
@@ -176,25 +178,37 @@ class UserCall:
|
|
|
176
178
|
)
|
|
177
179
|
|
|
178
180
|
if isinstance(message, ImageData):
|
|
179
|
-
message =
|
|
181
|
+
message = ImageMessage(
|
|
180
182
|
image=message,
|
|
181
|
-
message=Message(type="message", detail=""),
|
|
182
183
|
)
|
|
183
184
|
|
|
184
185
|
if isinstance(message, Message):
|
|
185
186
|
self.__send(message)
|
|
186
|
-
elif isinstance(message,
|
|
187
|
+
elif isinstance(message, ImageMessage):
|
|
187
188
|
self.__send_image(message)
|
|
188
189
|
else:
|
|
189
190
|
raise ValueError("Tipo de mensagem inválido.")
|
|
190
191
|
|
|
191
|
-
def
|
|
192
|
+
def __upload_file(self, image: ImageData) -> None:
|
|
193
|
+
dict_image = image.get_upload_dict()
|
|
194
|
+
response = self.__router_client.upload_file(dict_image)
|
|
195
|
+
|
|
196
|
+
if not response.status:
|
|
197
|
+
raise ValueError("Erro ao fazer upload do arquivo.")
|
|
198
|
+
else:
|
|
199
|
+
print("Arquivo enviado com sucesso.")
|
|
200
|
+
|
|
201
|
+
def __send_image(self, message: ImageMessage) -> None:
|
|
192
202
|
dict_message = message.to_dict()
|
|
193
203
|
dict_message["message"]["chat_id"] = self.__user_state.chatID.to_dict()
|
|
194
204
|
response = self.__router_client.send_image(dict_message)
|
|
195
205
|
|
|
196
|
-
if not response.status:
|
|
206
|
+
if not response.status and response.message != "arquivo não encontrado":
|
|
197
207
|
raise ValueError("Erro ao enviar imagem.")
|
|
208
|
+
elif response.message == "arquivo não encontrado":
|
|
209
|
+
self.__upload_file(message.image)
|
|
210
|
+
print("tentando enviar imagem novamente...")
|
|
211
|
+
self.__send_image(message)
|
|
198
212
|
|
|
199
213
|
def __send(self, message: Message) -> None:
|
|
200
214
|
|
|
@@ -208,14 +222,20 @@ class UserCall:
|
|
|
208
222
|
if not response.status:
|
|
209
223
|
raise ValueError("Erro ao enviar mensagem de botões.")
|
|
210
224
|
|
|
211
|
-
def transfer_to_human(
|
|
225
|
+
def transfer_to_human(
|
|
226
|
+
self, message: str, campaign_id: str = None, campaign_name: str = None
|
|
227
|
+
) -> None:
|
|
212
228
|
|
|
213
|
-
|
|
229
|
+
if campaign_id is None and campaign_name is None:
|
|
230
|
+
raise ValueError("Você deve informar o ID ou o nome da campanha.")
|
|
231
|
+
if not campaign_id:
|
|
232
|
+
campaign = self.__router_client.get_campaign_id({"name": campaign_name})
|
|
233
|
+
campaign_id = campaign.id
|
|
214
234
|
|
|
215
235
|
response = self.__router_client.transfer_to_human(
|
|
216
236
|
{
|
|
217
237
|
"chat_id": self.__user_state.chatID.to_dict(),
|
|
218
|
-
"campaign_id":
|
|
238
|
+
"campaign_id": campaign_id,
|
|
219
239
|
"observation": message,
|
|
220
240
|
}
|
|
221
241
|
)
|
|
@@ -236,13 +256,19 @@ class UserCall:
|
|
|
236
256
|
if not response.status:
|
|
237
257
|
raise ValueError("Erro ao transferir chat para menu.")
|
|
238
258
|
|
|
239
|
-
def end_chat(self, message: str, tabulation_name: str) -> None:
|
|
240
|
-
|
|
259
|
+
def end_chat(self, message: str, tabulation_id: str, tabulation_name: str) -> None:
|
|
260
|
+
if tabulation_id is None and tabulation_name is None:
|
|
261
|
+
raise ValueError("Você deve informar o ID ou o nome da tabulação.")
|
|
262
|
+
if not tabulation_id:
|
|
263
|
+
tabulation = self.__router_client.get_tabulation_id(
|
|
264
|
+
{"name": tabulation_name}
|
|
265
|
+
)
|
|
266
|
+
tabulation_id = tabulation.id
|
|
241
267
|
|
|
242
268
|
response = self.__router_client.end_chat(
|
|
243
269
|
{
|
|
244
270
|
"chat_id": self.__user_state.chatID.to_dict(),
|
|
245
|
-
"tabulation_id":
|
|
271
|
+
"tabulation_id": tabulation_id,
|
|
246
272
|
"observation": message,
|
|
247
273
|
}
|
|
248
274
|
)
|
|
@@ -328,3 +354,7 @@ class UserCall:
|
|
|
328
354
|
self.update_user_state(
|
|
329
355
|
self.__user_state.menu, self.__user_state.route, observation
|
|
330
356
|
)
|
|
357
|
+
|
|
358
|
+
@content_message.setter
|
|
359
|
+
def content_message(self, content_message: str):
|
|
360
|
+
self.__content_message = content_message
|
chatgraph/types/route.py
CHANGED
|
@@ -10,7 +10,7 @@ class Route:
|
|
|
10
10
|
routes (list[str]): A lista de todas as rotas disponíveis no fluxo.
|
|
11
11
|
"""
|
|
12
12
|
|
|
13
|
-
def __init__(self, current: str, routes: list[str], separator:str=
|
|
13
|
+
def __init__(self, current: str, routes: list[str], separator: str = "."):
|
|
14
14
|
"""
|
|
15
15
|
Inicializa a rota com a rota atual e a lista de rotas disponíveis.
|
|
16
16
|
|
|
@@ -24,20 +24,20 @@ class Route:
|
|
|
24
24
|
self.separator = separator
|
|
25
25
|
|
|
26
26
|
@property
|
|
27
|
-
def previous(self)->
|
|
27
|
+
def previous(self) -> "Route":
|
|
28
28
|
"""
|
|
29
29
|
Retorna a rota anterior a atual do usuário
|
|
30
30
|
"""
|
|
31
31
|
return self.get_previous()
|
|
32
|
-
|
|
32
|
+
|
|
33
33
|
@property
|
|
34
|
-
def current_node(self)->str:
|
|
34
|
+
def current_node(self) -> str:
|
|
35
35
|
"""
|
|
36
36
|
Retorna o nó atual do usuário
|
|
37
37
|
"""
|
|
38
38
|
return self.current.split(self.separator)[-1]
|
|
39
|
-
|
|
40
|
-
def get_previous(self) ->
|
|
39
|
+
|
|
40
|
+
def get_previous(self) -> "Route":
|
|
41
41
|
"""
|
|
42
42
|
Retorna o caminho anterior ao caminho atual.
|
|
43
43
|
|
|
@@ -47,13 +47,18 @@ class Route:
|
|
|
47
47
|
Returns:
|
|
48
48
|
str: O caminho anterior à rota atual.
|
|
49
49
|
"""
|
|
50
|
-
if self.current ==
|
|
50
|
+
if self.current == "start":
|
|
51
51
|
return Route(self.current, self.routes, self.separator)
|
|
52
52
|
|
|
53
|
-
|
|
53
|
+
rotas_dedup = self.separator.join(
|
|
54
|
+
dict.fromkeys(self.current.split(self.separator))
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
previous_route = self.separator.join(rotas_dedup.split(self.separator)[:-1])
|
|
58
|
+
|
|
54
59
|
return Route(previous_route, self.routes, self.separator)
|
|
55
60
|
|
|
56
|
-
def get_next(self, next_part: str) ->
|
|
61
|
+
def get_next(self, next_part: str) -> "Route":
|
|
57
62
|
"""
|
|
58
63
|
Monta e retorna o próximo caminho com base na parte fornecida.
|
|
59
64
|
|
|
@@ -69,8 +74,8 @@ class Route:
|
|
|
69
74
|
next_part = next_part.strip().lower()
|
|
70
75
|
next_route = f"{self.current.rstrip(self.separator)}.{next_part}"
|
|
71
76
|
if next_part not in self.routes:
|
|
72
|
-
raise RouteError(f
|
|
73
|
-
|
|
77
|
+
raise RouteError(f"Rota não encontrada: {next_part}")
|
|
78
|
+
|
|
74
79
|
return Route(next_route, self.routes, self.separator)
|
|
75
80
|
|
|
76
81
|
def __str__(self):
|
|
@@ -80,7 +85,7 @@ class Route:
|
|
|
80
85
|
Returns:
|
|
81
86
|
str: A representação em string da rota atual.
|
|
82
87
|
"""
|
|
83
|
-
return f
|
|
88
|
+
return f"Route(current={self.current})"
|
|
84
89
|
|
|
85
90
|
def __repr__(self):
|
|
86
91
|
"""
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
chatgraph/__init__.py,sha256=cQk87BOUYKvOjgCkS5Vexy9EYeLOeuQn6vR1vXx1Akc,935
|
|
2
|
+
chatgraph/auth/credentials.py,sha256=xsMEpLQnc66novPjL6upocMcnUnvFJ7yxINzUenkxmc,2388
|
|
3
|
+
chatgraph/bot/chatbot_model.py,sha256=kI990THIgwcwRm69XcfSqJkUAH1Khbm5OrfDnKxMZ8o,8446
|
|
4
|
+
chatgraph/bot/chatbot_router.py,sha256=bVbm9dBoC2OesetXlQJpCrkaiLM3GUro0GrOyCSgreI,2586
|
|
5
|
+
chatgraph/bot/default_functions.py,sha256=OSgo3NGxT4RwGe5ohpGksaARSDSkNInLmJsBuZAuv1Y,739
|
|
6
|
+
chatgraph/cli/__init__.py,sha256=tfgYhGoKy1nD4STN4xDh6J4VV55RICk7v1GZmzAg-bM,7413
|
|
7
|
+
chatgraph/error/chatbot_error.py,sha256=4sEcW8vz0eQk2QDmDygucVM4caHliZW5iH7XJvmLBuk,1897
|
|
8
|
+
chatgraph/error/route_error.py,sha256=CY8m82ap7-Sr-DXPsolltRW50TqD__5RyXBmNNJCWr8,793
|
|
9
|
+
chatgraph/gRPC/gRPCCall.py,sha256=jMWPbHobyR6n942BARsQSlVmbh6dk0qUpfVgSNlGOvg,7561
|
|
10
|
+
chatgraph/messages/message_consumer.py,sha256=yHhfLYjtmXQYG44o7SNO6XUaeM4-jH8BpIpPHI-mt8Y,6116
|
|
11
|
+
chatgraph/pb/router.proto,sha256=0FDhMe7GrabeQz7QRJN8PN2mcuRjA5YrGt6TC9GWBak,3488
|
|
12
|
+
chatgraph/pb/router_pb2.py,sha256=eSo0ncYDSG3ryIfWNFzqmG3anx-VmQ2nGXBy1gPnXmQ,7962
|
|
13
|
+
chatgraph/pb/router_pb2_grpc.py,sha256=iaQQsYPc8Tihuf4sWEI48DhvhtCYtDqFBHhwRtE57ps,29886
|
|
14
|
+
chatgraph/types/background_task.py,sha256=j-Bpd1l_LCDiWukhfG8wNr1F0_GUaOL_J2_BCUnTof4,928
|
|
15
|
+
chatgraph/types/end_types.py,sha256=QMNju3wpdbCpdUTSZ0oGQx9x0wgckxmw1wfGgowqCTk,2057
|
|
16
|
+
chatgraph/types/image.py,sha256=-Lf9ns8_M4jmROoFnHlZiYeScYD_GhF1pgIGLVjsRtI,3216
|
|
17
|
+
chatgraph/types/message_types.py,sha256=__LOk09Xfvojum0xiq9n157_3QSSLNaDMc02iq8dGpk,3434
|
|
18
|
+
chatgraph/types/request_types.py,sha256=DC-x4tR5WLxcI9wzaZ0bk82eeLaTOClQbal3F1KWG2w,11240
|
|
19
|
+
chatgraph/types/route.py,sha256=UUlMWje8yZ4scHp3LKXrtRXycDtudIwUpwQvi3zQ2_w,3090
|
|
20
|
+
chatgraph-0.6.2.dist-info/entry_points.txt,sha256=bO9_Q-PqE5vCNNo6ke_-3j2gHfKQMDGnKDTkNuCdBuA,48
|
|
21
|
+
chatgraph-0.6.2.dist-info/LICENSE,sha256=rVJozpRzDlplOpvI8A1GvmfVS0ReYdZvMWc1j2jV0v8,1090
|
|
22
|
+
chatgraph-0.6.2.dist-info/METADATA,sha256=-n5XOgBx9bxthqGX6W7TncIQKqXkncARgWvKcZH28FA,12908
|
|
23
|
+
chatgraph-0.6.2.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
24
|
+
chatgraph-0.6.2.dist-info/RECORD,,
|
chatgraph-0.6.0.dist-info/RECORD
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
chatgraph/__init__.py,sha256=ENRmvWkLHfwErug_flNYgbTa4MUMrIzMqGeaFSlSNhM,929
|
|
2
|
-
chatgraph/auth/credentials.py,sha256=xsMEpLQnc66novPjL6upocMcnUnvFJ7yxINzUenkxmc,2388
|
|
3
|
-
chatgraph/bot/chatbot_model.py,sha256=wLVXehmHEWItRwvl6J8HM96lC69FXmqsNG8KqplBboI,7373
|
|
4
|
-
chatgraph/bot/chatbot_router.py,sha256=bVbm9dBoC2OesetXlQJpCrkaiLM3GUro0GrOyCSgreI,2586
|
|
5
|
-
chatgraph/cli/__init__.py,sha256=tfgYhGoKy1nD4STN4xDh6J4VV55RICk7v1GZmzAg-bM,7413
|
|
6
|
-
chatgraph/error/chatbot_error.py,sha256=4sEcW8vz0eQk2QDmDygucVM4caHliZW5iH7XJvmLBuk,1897
|
|
7
|
-
chatgraph/error/route_error.py,sha256=CY8m82ap7-Sr-DXPsolltRW50TqD__5RyXBmNNJCWr8,793
|
|
8
|
-
chatgraph/gRPC/gRPCCall.py,sha256=8t3Il6C-x6LqvdiUOZ5absfVwAfEWY7MpEfmEVNMgVY,5776
|
|
9
|
-
chatgraph/messages/message_consumer.py,sha256=yHhfLYjtmXQYG44o7SNO6XUaeM4-jH8BpIpPHI-mt8Y,6116
|
|
10
|
-
chatgraph/pb/router.proto,sha256=DkP_ESSy2BNO7mMqtXAmFafsz4OLtxj-IoKBzeDout4,3308
|
|
11
|
-
chatgraph/pb/router_pb2.py,sha256=ohYjPoSwbYfFJp1JQIvi7F-BlrHkifeIEvF5KzfjD8g,7426
|
|
12
|
-
chatgraph/pb/router_pb2_grpc.py,sha256=-khhvX4epBDOqGUhQEhuJSAX_Kh7iJBG3csC18Aa73g,28287
|
|
13
|
-
chatgraph/types/background_task.py,sha256=j-Bpd1l_LCDiWukhfG8wNr1F0_GUaOL_J2_BCUnTof4,928
|
|
14
|
-
chatgraph/types/end_types.py,sha256=ulVq3XybRs-EGcOxw6e1FF6U2p3nbtPfOv3uRe6oJfo,1638
|
|
15
|
-
chatgraph/types/image.py,sha256=f2PnUo4Jp24Cn1F4NQhgeoGJPacQiMZCogVowjJwrIE,1097
|
|
16
|
-
chatgraph/types/message_types.py,sha256=__LOk09Xfvojum0xiq9n157_3QSSLNaDMc02iq8dGpk,3434
|
|
17
|
-
chatgraph/types/request_types.py,sha256=stiEDOtFxn22z2bpgYlIcfSM0ellqVbPaJC2noY8mwQ,9957
|
|
18
|
-
chatgraph/types/route.py,sha256=FO5INy5UXgicuQ8FKEZKcPv6WS5YH10dPx2OaPu_0sE,2978
|
|
19
|
-
chatgraph-0.6.0.dist-info/entry_points.txt,sha256=bO9_Q-PqE5vCNNo6ke_-3j2gHfKQMDGnKDTkNuCdBuA,48
|
|
20
|
-
chatgraph-0.6.0.dist-info/LICENSE,sha256=rVJozpRzDlplOpvI8A1GvmfVS0ReYdZvMWc1j2jV0v8,1090
|
|
21
|
-
chatgraph-0.6.0.dist-info/METADATA,sha256=L5LzW2b54Jj0GzFDBUOu_95HztOVbtCMB0VVa1ozjsA,12908
|
|
22
|
-
chatgraph-0.6.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
23
|
-
chatgraph-0.6.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|