MindsDB 25.3.3.0__py3-none-any.whl → 25.3.4.0__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 MindsDB might be problematic. Click here for more details.
- mindsdb/__about__.py +1 -1
- mindsdb/api/executor/datahub/datanodes/information_schema_datanode.py +2 -6
- mindsdb/api/executor/datahub/datanodes/mindsdb_tables.py +1 -1
- mindsdb/api/http/namespaces/agents.py +9 -5
- mindsdb/api/http/namespaces/chatbots.py +6 -5
- mindsdb/api/http/namespaces/databases.py +5 -6
- mindsdb/api/http/namespaces/skills.py +5 -4
- mindsdb/api/http/namespaces/views.py +6 -7
- mindsdb/integrations/handlers/chromadb_handler/chromadb_handler.py +23 -2
- mindsdb/integrations/handlers/dummy_data_handler/dummy_data_handler.py +16 -6
- mindsdb/integrations/handlers/file_handler/tests/test_file_handler.py +64 -83
- mindsdb/integrations/handlers/huggingface_handler/requirements.txt +5 -4
- mindsdb/integrations/handlers/huggingface_handler/requirements_cpu.txt +5 -5
- mindsdb/integrations/handlers/ms_one_drive_handler/ms_graph_api_one_drive_client.py +1 -1
- mindsdb/integrations/handlers/ms_teams_handler/ms_graph_api_teams_client.py +278 -0
- mindsdb/integrations/handlers/ms_teams_handler/ms_teams_handler.py +114 -70
- mindsdb/integrations/handlers/ms_teams_handler/ms_teams_tables.py +431 -0
- mindsdb/integrations/handlers/pgvector_handler/pgvector_handler.py +18 -4
- mindsdb/integrations/libs/vectordatabase_handler.py +2 -2
- mindsdb/integrations/utilities/files/file_reader.py +3 -3
- mindsdb/integrations/utilities/handlers/api_utilities/microsoft/ms_graph_api_utilities.py +36 -2
- mindsdb/integrations/utilities/rag/settings.py +1 -0
- mindsdb/interfaces/chatbot/chatbot_controller.py +6 -4
- mindsdb/interfaces/jobs/jobs_controller.py +1 -4
- mindsdb/interfaces/knowledge_base/controller.py +9 -28
- mindsdb/interfaces/knowledge_base/preprocessing/document_preprocessor.py +1 -1
- mindsdb/interfaces/skills/skills_controller.py +8 -7
- {mindsdb-25.3.3.0.dist-info → mindsdb-25.3.4.0.dist-info}/METADATA +221 -218
- {mindsdb-25.3.3.0.dist-info → mindsdb-25.3.4.0.dist-info}/RECORD +32 -30
- {mindsdb-25.3.3.0.dist-info → mindsdb-25.3.4.0.dist-info}/WHEEL +1 -1
- {mindsdb-25.3.3.0.dist-info → mindsdb-25.3.4.0.dist-info/licenses}/LICENSE +0 -0
- {mindsdb-25.3.3.0.dist-info → mindsdb-25.3.4.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
from typing import Text, List, Dict, Optional
|
|
2
|
+
|
|
3
|
+
from requests.exceptions import RequestException
|
|
4
|
+
|
|
5
|
+
from mindsdb.integrations.utilities.handlers.api_utilities.microsoft.ms_graph_api_utilities import MSGraphAPIBaseClient
|
|
6
|
+
from mindsdb.utilities import log
|
|
7
|
+
|
|
8
|
+
logger = log.getLogger(__name__)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class MSGraphAPITeamsDelegatedPermissionsClient(MSGraphAPIBaseClient):
|
|
12
|
+
"""
|
|
13
|
+
The Microsoft Graph API client for the Microsoft Teams handler with delegated permissions.
|
|
14
|
+
This client is used for accessing the Microsoft Teams specific endpoints of the Microsoft Graph API.
|
|
15
|
+
Several common methods for submitting requests, fetching data, etc. are inherited from the base class.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
def check_connection(self) -> bool:
|
|
19
|
+
"""
|
|
20
|
+
Check if the connection to Microsoft Teams is established.
|
|
21
|
+
|
|
22
|
+
Returns:
|
|
23
|
+
bool: True if the connection is established, False otherwise.
|
|
24
|
+
"""
|
|
25
|
+
try:
|
|
26
|
+
self.fetch_data_json("me/joinedTeams")
|
|
27
|
+
return True
|
|
28
|
+
except RequestException as request_error:
|
|
29
|
+
logger.error(f"Failed to check connection to Microsoft Teams: {request_error}")
|
|
30
|
+
return False
|
|
31
|
+
|
|
32
|
+
def get_all_groups(self) -> List[Dict]:
|
|
33
|
+
"""
|
|
34
|
+
Get all groups that the signed in user is a member of.
|
|
35
|
+
|
|
36
|
+
Returns:
|
|
37
|
+
List[Dict]: The groups data.
|
|
38
|
+
"""
|
|
39
|
+
return self.fetch_data_json("me/joinedTeams")
|
|
40
|
+
|
|
41
|
+
def _get_all_group_ids(self) -> List[Text]:
|
|
42
|
+
"""
|
|
43
|
+
Get all group IDs related to Microsoft Teams.
|
|
44
|
+
|
|
45
|
+
Returns:
|
|
46
|
+
List[Text]: The group IDs.
|
|
47
|
+
"""
|
|
48
|
+
if not self._group_ids:
|
|
49
|
+
groups = self.get_all_groups()
|
|
50
|
+
self._group_ids = [group["id"] for group in groups]
|
|
51
|
+
|
|
52
|
+
return self._group_ids
|
|
53
|
+
|
|
54
|
+
def get_channel_in_group_by_id(self, group_id: Text, channel_id: Text) -> Dict:
|
|
55
|
+
"""
|
|
56
|
+
Get a channel by its ID and the ID of the group that it belongs to.
|
|
57
|
+
|
|
58
|
+
Args:
|
|
59
|
+
group_id (Text): The ID of the group that the channel belongs to.
|
|
60
|
+
channel_id (Text): The ID of the channel.
|
|
61
|
+
|
|
62
|
+
Returns:
|
|
63
|
+
Dict: The channel data.
|
|
64
|
+
"""
|
|
65
|
+
channel = self.fetch_data_json(f"teams/{group_id}/channels/{channel_id}")
|
|
66
|
+
# Add the group ID to the channel data.
|
|
67
|
+
channel.update({"teamId": group_id})
|
|
68
|
+
|
|
69
|
+
return channel
|
|
70
|
+
|
|
71
|
+
def get_channels_in_group_by_ids(self, group_id: Text, channel_ids: List[Text]) -> List[Dict]:
|
|
72
|
+
"""
|
|
73
|
+
Get channels by their IDs and the ID of the group that they belong to.
|
|
74
|
+
|
|
75
|
+
Args:
|
|
76
|
+
group_id (Text): The ID of the group that the channels belong to.
|
|
77
|
+
channel_ids (List[Text]): The IDs of the channels.
|
|
78
|
+
|
|
79
|
+
Returns:
|
|
80
|
+
List[Dict]: The channels data.
|
|
81
|
+
"""
|
|
82
|
+
channels = []
|
|
83
|
+
for channel_id in channel_ids:
|
|
84
|
+
channels.append(self.get_channel_in_group_by_id(group_id, channel_id))
|
|
85
|
+
|
|
86
|
+
return channels
|
|
87
|
+
|
|
88
|
+
def get_all_channels_in_group(self, group_id: Text) -> List[Dict]:
|
|
89
|
+
"""
|
|
90
|
+
Get all channels of a group by its ID.
|
|
91
|
+
|
|
92
|
+
Args:
|
|
93
|
+
group_id (Text): The ID of the group.
|
|
94
|
+
|
|
95
|
+
Returns:
|
|
96
|
+
List[Dict]: The channels data.
|
|
97
|
+
"""
|
|
98
|
+
channels = self.fetch_data_json(f"teams/{group_id}/channels")
|
|
99
|
+
for channel in channels:
|
|
100
|
+
channel["teamId"] = group_id
|
|
101
|
+
|
|
102
|
+
return channels
|
|
103
|
+
|
|
104
|
+
def get_all_channels_across_all_groups(self) -> List[Dict]:
|
|
105
|
+
"""
|
|
106
|
+
Get all channels across all groups that the signed in user is a member of.
|
|
107
|
+
|
|
108
|
+
Returns:
|
|
109
|
+
List[Dict]: The channels data.
|
|
110
|
+
"""
|
|
111
|
+
channels = []
|
|
112
|
+
for group_id in self._get_all_group_ids():
|
|
113
|
+
channels += self.get_all_channels_in_group(group_id)
|
|
114
|
+
|
|
115
|
+
return channels
|
|
116
|
+
|
|
117
|
+
def get_channels_across_all_groups_by_ids(self, channel_ids: List[Text]) -> List[Dict]:
|
|
118
|
+
"""
|
|
119
|
+
Get channels by their IDs.
|
|
120
|
+
|
|
121
|
+
Args:
|
|
122
|
+
channel_ids (List[Text]): The IDs of the channels.
|
|
123
|
+
|
|
124
|
+
Returns:
|
|
125
|
+
List[Dict]: The channels data.
|
|
126
|
+
"""
|
|
127
|
+
channels = self.get_all_channels_across_all_groups()
|
|
128
|
+
|
|
129
|
+
return [channel for channel in channels if channel["id"] in channel_ids]
|
|
130
|
+
|
|
131
|
+
def get_message_in_channel_by_id(self, group_id: Text, channel_id: Text, message_id: Text) -> Dict:
|
|
132
|
+
"""
|
|
133
|
+
Get a message by its ID, the ID of the group that it belongs to, and the ID of the channel that it belongs to.
|
|
134
|
+
|
|
135
|
+
Args:
|
|
136
|
+
group_id (Text): The ID of the group that the channel belongs to.
|
|
137
|
+
channel_id (Text): The ID of the channel that the message belongs to.
|
|
138
|
+
message_id (Text): The ID of the message.
|
|
139
|
+
|
|
140
|
+
Returns:
|
|
141
|
+
Dict: The message data.
|
|
142
|
+
"""
|
|
143
|
+
return self.fetch_data_json(f"teams/{group_id}/channels/{channel_id}/messages/{message_id}")
|
|
144
|
+
|
|
145
|
+
def get_messages_in_channel_by_ids(self, group_id: Text, channel_id: Text, message_ids: List[Text]) -> List[Dict]:
|
|
146
|
+
"""
|
|
147
|
+
Get messages by their IDs, the ID of the group that they belong to, and the ID of the channel that they belong to.
|
|
148
|
+
|
|
149
|
+
Args:
|
|
150
|
+
group_id (Text): The ID of the group that the channel belongs to.
|
|
151
|
+
channel_id (Text): The ID of the channel that the messages belong to.
|
|
152
|
+
message_ids (List[Text]): The IDs of the messages.
|
|
153
|
+
|
|
154
|
+
Returns:
|
|
155
|
+
List[Dict]: The messages data.
|
|
156
|
+
"""
|
|
157
|
+
messages = []
|
|
158
|
+
for message_id in message_ids:
|
|
159
|
+
messages.append(self.get_message_in_channel_by_id(group_id, channel_id, message_id))
|
|
160
|
+
|
|
161
|
+
return messages
|
|
162
|
+
|
|
163
|
+
def get_all_messages_in_channel(self, group_id: Text, channel_id: Text, limit: int = None) -> List[Dict]:
|
|
164
|
+
"""
|
|
165
|
+
Get messages of a channel by its ID and the ID of the group that it belongs to.
|
|
166
|
+
|
|
167
|
+
Args:
|
|
168
|
+
group_id (Text): The ID of the group that the channel belongs to.
|
|
169
|
+
channel_id (Text): The ID of the channel.
|
|
170
|
+
|
|
171
|
+
Returns:
|
|
172
|
+
List[Dict]: The messages data.
|
|
173
|
+
"""
|
|
174
|
+
messages = []
|
|
175
|
+
for messages_batch in self.fetch_paginated_data(f"teams/{group_id}/channels/{channel_id}/messages"):
|
|
176
|
+
messages += messages_batch
|
|
177
|
+
|
|
178
|
+
if limit and len(messages) >= limit:
|
|
179
|
+
break
|
|
180
|
+
|
|
181
|
+
return messages[:limit]
|
|
182
|
+
|
|
183
|
+
def get_chat_by_id(self, chat_id: Text) -> Dict:
|
|
184
|
+
"""
|
|
185
|
+
Get a chat by its ID.
|
|
186
|
+
|
|
187
|
+
Args:
|
|
188
|
+
chat_id (Text): The ID of the chat.
|
|
189
|
+
|
|
190
|
+
Returns:
|
|
191
|
+
Dict: The chat data.
|
|
192
|
+
"""
|
|
193
|
+
return self.fetch_data_json(f"/me/chats/{chat_id}")
|
|
194
|
+
|
|
195
|
+
def get_chats_by_ids(self, chat_ids: List[Text]) -> List[Dict]:
|
|
196
|
+
"""
|
|
197
|
+
Get chats by their IDs.
|
|
198
|
+
|
|
199
|
+
Args:
|
|
200
|
+
chat_ids (List[Text]): The IDs of the chats.
|
|
201
|
+
|
|
202
|
+
Returns:
|
|
203
|
+
List[Dict]: The chats data.
|
|
204
|
+
"""
|
|
205
|
+
chats = []
|
|
206
|
+
for chat_id in chat_ids:
|
|
207
|
+
chats.append(self.get_chat_by_id(chat_id))
|
|
208
|
+
|
|
209
|
+
return chats
|
|
210
|
+
|
|
211
|
+
def get_all_chats(self, limit: int = None) -> List[Dict]:
|
|
212
|
+
"""
|
|
213
|
+
Get all chats of the signed in user.
|
|
214
|
+
|
|
215
|
+
Args:
|
|
216
|
+
limit (int): The maximum number of chats to return.
|
|
217
|
+
|
|
218
|
+
Returns:
|
|
219
|
+
List[Dict]: The chats data.
|
|
220
|
+
"""
|
|
221
|
+
chats = []
|
|
222
|
+
for chat_batch in self.fetch_paginated_data("me/chats"):
|
|
223
|
+
chats += chat_batch
|
|
224
|
+
|
|
225
|
+
if limit and len(chats) >= limit:
|
|
226
|
+
break
|
|
227
|
+
|
|
228
|
+
return chats[:limit]
|
|
229
|
+
|
|
230
|
+
def get_message_in_chat_by_id(self, chat_id: Text, message_id: Text) -> Dict:
|
|
231
|
+
"""
|
|
232
|
+
Get a message by its ID and the ID of the chat that it belongs to.
|
|
233
|
+
|
|
234
|
+
Args:
|
|
235
|
+
chat_id (Text): The ID of the chat that the message belongs to.
|
|
236
|
+
message_id (Text): The ID of the message.
|
|
237
|
+
|
|
238
|
+
Returns:
|
|
239
|
+
Dict: The message data.
|
|
240
|
+
"""
|
|
241
|
+
return self.fetch_data_json(f"me/chats/{chat_id}/messages/{message_id}")
|
|
242
|
+
|
|
243
|
+
def get_messages_in_chat_by_ids(self, chat_id: Text, message_ids: List[Text]) -> List[Dict]:
|
|
244
|
+
"""
|
|
245
|
+
Get messages by their IDs and the ID of the chat that they belong to.
|
|
246
|
+
|
|
247
|
+
Args:
|
|
248
|
+
chat_id (Text): The ID of the chat that the messages belong to.
|
|
249
|
+
message_ids (List[Text]): The IDs of the messages.
|
|
250
|
+
|
|
251
|
+
Returns:
|
|
252
|
+
List[Dict]: The messages data.
|
|
253
|
+
"""
|
|
254
|
+
messages = []
|
|
255
|
+
for message_id in message_ids:
|
|
256
|
+
messages.append(self.get_message_in_chat_by_id(chat_id, message_id))
|
|
257
|
+
|
|
258
|
+
return messages
|
|
259
|
+
|
|
260
|
+
def get_all_messages_in_chat(self, chat_id: Text, limit: int = None) -> List[Dict]:
|
|
261
|
+
"""
|
|
262
|
+
Get messages of a chat by its ID.
|
|
263
|
+
|
|
264
|
+
Args:
|
|
265
|
+
chat_id (Text): The ID of the chat.
|
|
266
|
+
|
|
267
|
+
Returns:
|
|
268
|
+
List[Dict]: The messages data.
|
|
269
|
+
"""
|
|
270
|
+
messages = []
|
|
271
|
+
for messages_batch in self.fetch_paginated_data(f"me/chats/{chat_id}/messages"):
|
|
272
|
+
messages += messages_batch
|
|
273
|
+
|
|
274
|
+
if limit and len(messages) >= limit:
|
|
275
|
+
break
|
|
276
|
+
|
|
277
|
+
return messages[:limit]
|
|
278
|
+
|
|
@@ -1,31 +1,48 @@
|
|
|
1
|
-
from typing import
|
|
1
|
+
from typing import Callable, Dict, Text, Callable, Union
|
|
2
2
|
|
|
3
3
|
from botbuilder.schema import Activity, ActivityTypes
|
|
4
4
|
from botbuilder.schema import ChannelAccount
|
|
5
5
|
from botframework.connector import ConnectorClient
|
|
6
6
|
from botframework.connector.auth import MicrosoftAppCredentials
|
|
7
|
-
|
|
8
|
-
from
|
|
7
|
+
import msal
|
|
8
|
+
from requests.exceptions import RequestException
|
|
9
9
|
|
|
10
|
+
from mindsdb.integrations.handlers.ms_teams_handler.ms_graph_api_teams_client import MSGraphAPITeamsDelegatedPermissionsClient
|
|
11
|
+
from mindsdb.integrations.handlers.ms_teams_handler.ms_teams_tables import (
|
|
12
|
+
ChannelsTable, ChannelMessagesTable, ChatsTable, ChatMessagesTable, TeamsTable
|
|
13
|
+
)
|
|
10
14
|
from mindsdb.integrations.libs.response import (
|
|
11
15
|
HandlerStatusResponse as StatusResponse,
|
|
12
16
|
)
|
|
13
17
|
from mindsdb.integrations.libs.api_handler import APIChatHandler
|
|
18
|
+
from mindsdb.integrations.utilities.handlers.auth_utilities import MSGraphAPIDelegatedPermissionsManager
|
|
19
|
+
from mindsdb.integrations.utilities.handlers.auth_utilities.exceptions import AuthException
|
|
14
20
|
from mindsdb.interfaces.chatbot.types import ChatBotMessage
|
|
21
|
+
from mindsdb.utilities import log
|
|
15
22
|
|
|
16
23
|
logger = log.getLogger(__name__)
|
|
17
24
|
|
|
18
25
|
|
|
26
|
+
def chatbot_only(func):
|
|
27
|
+
def wrapper(self, *args, **kwargs):
|
|
28
|
+
if self.connection_data.get('mode', 'chat') != 'chat':
|
|
29
|
+
raise ValueError("This connection can only be used as a data source. Please use a chatbot connection by setting the 'mode' parameter to 'chat'.")
|
|
30
|
+
return func(self, *args, **kwargs)
|
|
31
|
+
return wrapper
|
|
32
|
+
|
|
33
|
+
|
|
19
34
|
class MSTeamsHandler(APIChatHandler):
|
|
20
35
|
"""
|
|
21
|
-
|
|
36
|
+
This handler handles the connection and execution of SQL statements on Microsoft Teams via the Microsoft Graph API.
|
|
37
|
+
It is also responsible for handling the chatbot functionality.
|
|
22
38
|
"""
|
|
23
39
|
|
|
24
40
|
name = 'teams'
|
|
25
41
|
|
|
26
42
|
def __init__(self, name: str, **kwargs):
|
|
27
43
|
"""
|
|
28
|
-
|
|
44
|
+
Initializes the handler.
|
|
45
|
+
|
|
29
46
|
Args:
|
|
30
47
|
name (str): name of particular handler instance
|
|
31
48
|
**kwargs: arbitrary keyword arguments.
|
|
@@ -34,6 +51,7 @@ class MSTeamsHandler(APIChatHandler):
|
|
|
34
51
|
|
|
35
52
|
connection_data = kwargs.get("connection_data", {})
|
|
36
53
|
self.connection_data = connection_data
|
|
54
|
+
self.handler_storage = kwargs['handler_storage']
|
|
37
55
|
self.kwargs = kwargs
|
|
38
56
|
|
|
39
57
|
self.connection = None
|
|
@@ -44,22 +62,57 @@ class MSTeamsHandler(APIChatHandler):
|
|
|
44
62
|
self.bot_id = None
|
|
45
63
|
self.conversation_id = None
|
|
46
64
|
|
|
47
|
-
def connect(self) -> MicrosoftAppCredentials:
|
|
65
|
+
def connect(self) -> Union[MicrosoftAppCredentials, MSGraphAPITeamsDelegatedPermissionsClient]:
|
|
48
66
|
"""
|
|
49
|
-
|
|
67
|
+
Establishes a connection to the Microsoft Teams registered app or the Microsoft Graph API.
|
|
50
68
|
|
|
51
|
-
Returns
|
|
52
|
-
|
|
53
|
-
MicrosoftAppCredentials
|
|
54
|
-
Client object for interacting with the Microsoft Teams app.
|
|
69
|
+
Returns:
|
|
70
|
+
Union[MicrosoftAppCredentials, MSGraphAPITeamsDelegatedPermissionsClient]: A connection object to the Microsoft Teams registered app or the Microsoft Graph API.
|
|
55
71
|
"""
|
|
56
72
|
if self.is_connected:
|
|
57
73
|
return self.connection
|
|
58
74
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
75
|
+
# The default mode is 'data'. This is used for data source connections.
|
|
76
|
+
if self.connection_data.get('mode', 'data') == 'chat':
|
|
77
|
+
self.connection = MicrosoftAppCredentials(
|
|
78
|
+
app_id=self.connection_data["client_id"],
|
|
79
|
+
password=self.connection_data["client_secret"]
|
|
80
|
+
)
|
|
81
|
+
else:
|
|
82
|
+
# Initialize the token cache.
|
|
83
|
+
cache = msal.SerializableTokenCache()
|
|
84
|
+
|
|
85
|
+
# Load the cache from file if it exists.
|
|
86
|
+
cache_file = 'cache.bin'
|
|
87
|
+
try:
|
|
88
|
+
cache_content = self.handler_storage.file_get(cache_file)
|
|
89
|
+
except FileNotFoundError:
|
|
90
|
+
cache_content = None
|
|
91
|
+
|
|
92
|
+
if cache_content:
|
|
93
|
+
cache.deserialize(cache_content)
|
|
94
|
+
|
|
95
|
+
permissions_manager = MSGraphAPIDelegatedPermissionsManager(
|
|
96
|
+
client_id=self.connection_data['client_id'],
|
|
97
|
+
client_secret=self.connection_data['client_secret'],
|
|
98
|
+
tenant_id=self.connection_data['tenant_id'],
|
|
99
|
+
cache=cache,
|
|
100
|
+
code=self.connection_data.get('code')
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
access_token = permissions_manager.get_access_token()
|
|
104
|
+
|
|
105
|
+
# Save the cache back to file if it has changed.
|
|
106
|
+
if cache.has_state_changed:
|
|
107
|
+
self.handler_storage.file_set(cache_file, cache.serialize().encode('utf-8'))
|
|
108
|
+
|
|
109
|
+
self.connection = MSGraphAPITeamsDelegatedPermissionsClient(access_token)
|
|
110
|
+
|
|
111
|
+
self._register_table('channels', ChannelsTable(self))
|
|
112
|
+
self._register_table('channel_messages', ChannelMessagesTable(self))
|
|
113
|
+
self._register_table('chats', ChatsTable(self))
|
|
114
|
+
self._register_table('chat_messages', ChatMessagesTable(self))
|
|
115
|
+
self._register_table('teams', TeamsTable(self))
|
|
63
116
|
|
|
64
117
|
self.is_connected = True
|
|
65
118
|
|
|
@@ -67,54 +120,44 @@ class MSTeamsHandler(APIChatHandler):
|
|
|
67
120
|
|
|
68
121
|
def check_connection(self) -> StatusResponse:
|
|
69
122
|
"""
|
|
70
|
-
|
|
123
|
+
Checks the status of the connection to Microsoft Teams.
|
|
71
124
|
|
|
72
|
-
Returns
|
|
73
|
-
|
|
74
|
-
StatusResponse
|
|
75
|
-
Response object with the status of the connection.
|
|
125
|
+
Returns:
|
|
126
|
+
StatusResponse: An object containing the success status and an error message if an error occurs.
|
|
76
127
|
"""
|
|
77
128
|
response = StatusResponse(False)
|
|
78
129
|
|
|
79
130
|
try:
|
|
80
|
-
self.connect()
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
131
|
+
connection = self.connect()
|
|
132
|
+
# A connection check against the Microsoft Graph API is run if the connection is in 'data' mode.
|
|
133
|
+
if self.connection_data.get('mode', 'data') == 'data' and connection.check_connection():
|
|
134
|
+
response.success = True
|
|
135
|
+
response.copy_storage = True
|
|
136
|
+
else:
|
|
137
|
+
raise RequestException("Connection check failed!")
|
|
138
|
+
except (ValueError, RequestException) as known_error:
|
|
139
|
+
logger.error(f'Connection check to Microsoft Teams failed, {known_error}!')
|
|
140
|
+
response.error_message = str(known_error)
|
|
141
|
+
except AuthException as error:
|
|
142
|
+
response.error_message = str(error)
|
|
143
|
+
response.redirect_url = error.auth_url
|
|
144
|
+
return response
|
|
145
|
+
except Exception as unknown_error:
|
|
146
|
+
logger.error(f'Connection check to Microsoft Teams failed due to an unknown error, {unknown_error}!')
|
|
147
|
+
response.error_message = str(unknown_error)
|
|
86
148
|
|
|
87
149
|
self.is_connected = response.success
|
|
88
150
|
|
|
89
151
|
return response
|
|
90
152
|
|
|
91
|
-
|
|
92
|
-
"""
|
|
93
|
-
Receive and process a raw query.
|
|
94
|
-
|
|
95
|
-
Parameters
|
|
96
|
-
----------
|
|
97
|
-
query: Text
|
|
98
|
-
Query in the native format.
|
|
99
|
-
|
|
100
|
-
Returns
|
|
101
|
-
-------
|
|
102
|
-
StatusResponse
|
|
103
|
-
Response object with the result of the query.
|
|
104
|
-
"""
|
|
105
|
-
ast = parse_sql(query)
|
|
106
|
-
|
|
107
|
-
return self.query(ast)
|
|
108
|
-
|
|
153
|
+
@chatbot_only
|
|
109
154
|
def get_chat_config(self) -> Dict:
|
|
110
155
|
"""
|
|
111
|
-
|
|
156
|
+
Gets the configuration for the chatbot.
|
|
112
157
|
This method is required for the implementation of the chatbot.
|
|
113
158
|
|
|
114
|
-
Returns
|
|
115
|
-
|
|
116
|
-
Dict
|
|
117
|
-
Configuration for the chatbot.
|
|
159
|
+
Returns:
|
|
160
|
+
Dict: The configuration for the chatbot.
|
|
118
161
|
"""
|
|
119
162
|
params = {
|
|
120
163
|
'polling': {
|
|
@@ -123,30 +166,26 @@ class MSTeamsHandler(APIChatHandler):
|
|
|
123
166
|
}
|
|
124
167
|
|
|
125
168
|
return params
|
|
126
|
-
|
|
169
|
+
|
|
170
|
+
@chatbot_only
|
|
127
171
|
def get_my_user_name(self) -> Text:
|
|
128
172
|
"""
|
|
129
|
-
|
|
173
|
+
Gets the name of the signed in user.
|
|
130
174
|
This method is required for the implementation of the chatbot.
|
|
131
175
|
|
|
132
|
-
Returns
|
|
133
|
-
|
|
134
|
-
Text
|
|
135
|
-
Name of the signed in user.
|
|
176
|
+
Returns:
|
|
177
|
+
Text: The name of the signed in user.
|
|
136
178
|
"""
|
|
137
179
|
return None
|
|
138
|
-
|
|
180
|
+
|
|
181
|
+
@chatbot_only
|
|
139
182
|
def on_webhook(self, request: Dict, callback: Callable) -> None:
|
|
140
183
|
"""
|
|
141
|
-
|
|
184
|
+
Handles a webhook request.
|
|
142
185
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
The incoming webhook request.
|
|
147
|
-
|
|
148
|
-
callback: Callable
|
|
149
|
-
Callback function to call after parsing the request.
|
|
186
|
+
Args:
|
|
187
|
+
request (Dict): The request data.
|
|
188
|
+
callback (Callable): The callback function to call.
|
|
150
189
|
"""
|
|
151
190
|
self.service_url = request["serviceUrl"]
|
|
152
191
|
self.channel_id = request["channelId"]
|
|
@@ -164,15 +203,20 @@ class MSTeamsHandler(APIChatHandler):
|
|
|
164
203
|
chat_id=request['conversation']['id'],
|
|
165
204
|
message=chat_bot_message
|
|
166
205
|
)
|
|
167
|
-
|
|
206
|
+
|
|
207
|
+
@chatbot_only
|
|
168
208
|
def respond(self, message: ChatBotMessage) -> None:
|
|
169
209
|
"""
|
|
170
|
-
|
|
210
|
+
Sends a response to the chatbot.
|
|
211
|
+
|
|
212
|
+
Args:
|
|
213
|
+
message (ChatBotMessage): The message to send
|
|
214
|
+
|
|
215
|
+
Raises:
|
|
216
|
+
ValueError: If the chatbot message is not of type DIRECT.
|
|
171
217
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
message: ChatBotMessage
|
|
175
|
-
The message to send.
|
|
218
|
+
Returns:
|
|
219
|
+
None
|
|
176
220
|
"""
|
|
177
221
|
credentials = self.connect()
|
|
178
222
|
|