microsoft-agents-hosting-teams 0.0.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.
- microsoft/agents/hosting/teams/__init__.py +4 -0
- microsoft/agents/hosting/teams/teams_activity_handler.py +910 -0
- microsoft/agents/hosting/teams/teams_cloud_adapter.py +0 -0
- microsoft/agents/hosting/teams/teams_info.py +653 -0
- microsoft_agents_hosting_teams-0.0.0.dist-info/METADATA +13 -0
- microsoft_agents_hosting_teams-0.0.0.dist-info/RECORD +8 -0
- microsoft_agents_hosting_teams-0.0.0.dist-info/WHEEL +5 -0
- microsoft_agents_hosting_teams-0.0.0.dist-info/top_level.txt +1 -0
|
File without changes
|
|
@@ -0,0 +1,653 @@
|
|
|
1
|
+
# Copyright (c) Microsoft Corporation. All rights reserved.
|
|
2
|
+
# Licensed under the MIT License.
|
|
3
|
+
|
|
4
|
+
"""Teams information utilities for Microsoft Agents."""
|
|
5
|
+
|
|
6
|
+
from typing import Optional, Tuple, Dict, Any, List
|
|
7
|
+
|
|
8
|
+
from microsoft.agents.activity import Activity, Channels, ConversationParameters
|
|
9
|
+
|
|
10
|
+
from microsoft.agents.activity.teams import (
|
|
11
|
+
TeamsChannelAccount,
|
|
12
|
+
TeamsMeetingParticipant,
|
|
13
|
+
MeetingInfo,
|
|
14
|
+
TeamDetails,
|
|
15
|
+
TeamsPagedMembersResult,
|
|
16
|
+
MeetingNotification,
|
|
17
|
+
MeetingNotificationResponse,
|
|
18
|
+
TeamsMember,
|
|
19
|
+
BatchOperationStateResponse,
|
|
20
|
+
BatchFailedEntriesResponse,
|
|
21
|
+
CancelOperationResponse,
|
|
22
|
+
TeamsBatchOperationResponse,
|
|
23
|
+
ChannelInfo,
|
|
24
|
+
)
|
|
25
|
+
from microsoft.agents.hosting.core.connector.teams import TeamsConnectorClient
|
|
26
|
+
from microsoft.agents.hosting.core import ChannelServiceAdapter, TurnContext
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class TeamsInfo:
|
|
30
|
+
"""Teams information utilities for interacting with Teams-specific data."""
|
|
31
|
+
|
|
32
|
+
@staticmethod
|
|
33
|
+
async def get_meeting_participant(
|
|
34
|
+
context: TurnContext,
|
|
35
|
+
meeting_id: Optional[str] = None,
|
|
36
|
+
participant_id: Optional[str] = None,
|
|
37
|
+
tenant_id: Optional[str] = None,
|
|
38
|
+
) -> TeamsMeetingParticipant:
|
|
39
|
+
"""
|
|
40
|
+
Gets the meeting participant information.
|
|
41
|
+
|
|
42
|
+
Args:
|
|
43
|
+
context: The turn context.
|
|
44
|
+
meeting_id: The meeting ID. If not provided, it will be extracted from the activity.
|
|
45
|
+
participant_id: The participant ID. If not provided, it will be extracted from the activity.
|
|
46
|
+
tenant_id: The tenant ID. If not provided, it will be extracted from the activity.
|
|
47
|
+
|
|
48
|
+
Returns:
|
|
49
|
+
The meeting participant information.
|
|
50
|
+
|
|
51
|
+
Raises:
|
|
52
|
+
ValueError: If required parameters are missing.
|
|
53
|
+
"""
|
|
54
|
+
if not context:
|
|
55
|
+
raise ValueError("context is required.")
|
|
56
|
+
|
|
57
|
+
activity = context.activity
|
|
58
|
+
teams_channel_data: dict = activity.channel_data
|
|
59
|
+
|
|
60
|
+
if meeting_id is None:
|
|
61
|
+
meeting_id = teams_channel_data.get("meeting", {}).get("id", None)
|
|
62
|
+
|
|
63
|
+
if not meeting_id:
|
|
64
|
+
raise ValueError("meeting_id is required.")
|
|
65
|
+
|
|
66
|
+
if participant_id is None:
|
|
67
|
+
participant_id = getattr(activity.from_property, "aad_object_id", None)
|
|
68
|
+
|
|
69
|
+
if not participant_id:
|
|
70
|
+
raise ValueError("participant_id is required.")
|
|
71
|
+
|
|
72
|
+
if tenant_id is None:
|
|
73
|
+
tenant_id = teams_channel_data.get("tenant", {}).get("id", None)
|
|
74
|
+
|
|
75
|
+
rest_client = TeamsInfo._get_rest_client(context)
|
|
76
|
+
result = await rest_client.fetch_meeting_participant(
|
|
77
|
+
meeting_id, participant_id, tenant_id
|
|
78
|
+
)
|
|
79
|
+
return result
|
|
80
|
+
|
|
81
|
+
@staticmethod
|
|
82
|
+
async def get_meeting_info(
|
|
83
|
+
context: TurnContext, meeting_id: Optional[str] = None
|
|
84
|
+
) -> MeetingInfo:
|
|
85
|
+
"""
|
|
86
|
+
Gets the meeting information.
|
|
87
|
+
|
|
88
|
+
Args:
|
|
89
|
+
context: The turn context.
|
|
90
|
+
meeting_id: The meeting ID. If not provided, it will be extracted from the activity.
|
|
91
|
+
|
|
92
|
+
Returns:
|
|
93
|
+
The meeting information.
|
|
94
|
+
|
|
95
|
+
Raises:
|
|
96
|
+
ValueError: If required parameters are missing.
|
|
97
|
+
"""
|
|
98
|
+
if not meeting_id:
|
|
99
|
+
teams_channel_data: dict = context.activity.channel_data
|
|
100
|
+
meeting_id = teams_channel_data.get("meeting", {}).get("id", None)
|
|
101
|
+
|
|
102
|
+
if not meeting_id:
|
|
103
|
+
raise ValueError("meeting_id is required.")
|
|
104
|
+
|
|
105
|
+
rest_client = TeamsInfo._get_rest_client(context)
|
|
106
|
+
result = await rest_client.fetch_meeting_info(meeting_id)
|
|
107
|
+
return result
|
|
108
|
+
|
|
109
|
+
@staticmethod
|
|
110
|
+
async def get_team_details(
|
|
111
|
+
context: TurnContext, team_id: Optional[str] = None
|
|
112
|
+
) -> TeamDetails:
|
|
113
|
+
"""
|
|
114
|
+
Gets the team details.
|
|
115
|
+
|
|
116
|
+
Args:
|
|
117
|
+
context: The turn context.
|
|
118
|
+
team_id: The team ID. If not provided, it will be extracted from the activity.
|
|
119
|
+
|
|
120
|
+
Returns:
|
|
121
|
+
The team details.
|
|
122
|
+
|
|
123
|
+
Raises:
|
|
124
|
+
ValueError: If required parameters are missing.
|
|
125
|
+
"""
|
|
126
|
+
if not team_id:
|
|
127
|
+
teams_channel_data: dict = context.activity.channel_data
|
|
128
|
+
team_id = teams_channel_data.get("team", {}).get("id", None)
|
|
129
|
+
|
|
130
|
+
if not team_id:
|
|
131
|
+
raise ValueError("team_id is required.")
|
|
132
|
+
|
|
133
|
+
rest_client = TeamsInfo._get_rest_client(context)
|
|
134
|
+
result = await rest_client.fetch_team_details(team_id)
|
|
135
|
+
return result
|
|
136
|
+
|
|
137
|
+
@staticmethod
|
|
138
|
+
async def send_message_to_teams_channel(
|
|
139
|
+
context: TurnContext,
|
|
140
|
+
activity: Activity,
|
|
141
|
+
teams_channel_id: str,
|
|
142
|
+
app_id: Optional[str] = None,
|
|
143
|
+
) -> Tuple[Dict[str, Any], str]:
|
|
144
|
+
"""
|
|
145
|
+
Sends a message to a Teams channel.
|
|
146
|
+
|
|
147
|
+
Args:
|
|
148
|
+
context: The turn context.
|
|
149
|
+
activity: The activity to send.
|
|
150
|
+
teams_channel_id: The Teams channel ID.
|
|
151
|
+
app_id: The application ID.
|
|
152
|
+
|
|
153
|
+
Returns:
|
|
154
|
+
A tuple containing the conversation reference and new activity ID.
|
|
155
|
+
|
|
156
|
+
Raises:
|
|
157
|
+
ValueError: If required parameters are missing.
|
|
158
|
+
"""
|
|
159
|
+
if not context:
|
|
160
|
+
raise ValueError("TurnContext cannot be None")
|
|
161
|
+
|
|
162
|
+
if not activity:
|
|
163
|
+
raise ValueError("Activity cannot be None")
|
|
164
|
+
|
|
165
|
+
if not teams_channel_id:
|
|
166
|
+
raise ValueError("The teams_channel_id cannot be None or empty")
|
|
167
|
+
|
|
168
|
+
convo_params = ConversationParameters(
|
|
169
|
+
is_group=True,
|
|
170
|
+
channel_data={
|
|
171
|
+
"channel": {
|
|
172
|
+
"id": teams_channel_id,
|
|
173
|
+
},
|
|
174
|
+
},
|
|
175
|
+
activity=activity,
|
|
176
|
+
agent=context.activity.recipient,
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
conversation_reference = None
|
|
180
|
+
new_activity_id = None
|
|
181
|
+
|
|
182
|
+
if app_id and isinstance(context.adapter, ChannelServiceAdapter):
|
|
183
|
+
|
|
184
|
+
async def _conversation_callback(
|
|
185
|
+
turn_context: TurnContext,
|
|
186
|
+
) -> None:
|
|
187
|
+
"""
|
|
188
|
+
Callback for create_conversation.
|
|
189
|
+
|
|
190
|
+
Args:
|
|
191
|
+
turn_context: The turn context.
|
|
192
|
+
conversation_reference: The conversation reference to update.
|
|
193
|
+
new_activity_id: The new activity ID to update.
|
|
194
|
+
"""
|
|
195
|
+
nonlocal conversation_reference, new_activity_id
|
|
196
|
+
conversation_reference = (
|
|
197
|
+
turn_context.activity.get_conversation_reference()
|
|
198
|
+
)
|
|
199
|
+
new_activity_id = turn_context.activity.id
|
|
200
|
+
|
|
201
|
+
await context.adapter.create_conversation(
|
|
202
|
+
app_id,
|
|
203
|
+
Channels.ms_teams,
|
|
204
|
+
context.activity.service_url,
|
|
205
|
+
"https://api.botframework.com",
|
|
206
|
+
convo_params,
|
|
207
|
+
_conversation_callback,
|
|
208
|
+
)
|
|
209
|
+
else:
|
|
210
|
+
connector_client = TeamsInfo._get_rest_client(context)
|
|
211
|
+
conversation_resource_response = (
|
|
212
|
+
await connector_client.conversations.create_conversation(convo_params)
|
|
213
|
+
)
|
|
214
|
+
conversation_reference = context.activity.get_conversation_reference()
|
|
215
|
+
conversation_reference.conversation.id = conversation_resource_response.id
|
|
216
|
+
new_activity_id = conversation_resource_response.activity_id
|
|
217
|
+
|
|
218
|
+
return conversation_reference, new_activity_id
|
|
219
|
+
|
|
220
|
+
@staticmethod
|
|
221
|
+
async def get_team_channels(
|
|
222
|
+
context: TurnContext, team_id: Optional[str] = None
|
|
223
|
+
) -> List[ChannelInfo]:
|
|
224
|
+
"""
|
|
225
|
+
Gets the channels of a team.
|
|
226
|
+
|
|
227
|
+
Args:
|
|
228
|
+
context: The turn context.
|
|
229
|
+
team_id: The team ID. If not provided, it will be extracted from the activity.
|
|
230
|
+
|
|
231
|
+
Returns:
|
|
232
|
+
The list of channels.
|
|
233
|
+
|
|
234
|
+
Raises:
|
|
235
|
+
ValueError: If required parameters are missing.
|
|
236
|
+
"""
|
|
237
|
+
if not team_id:
|
|
238
|
+
teams_channel_data: dict = context.activity.channel_data
|
|
239
|
+
team_id = teams_channel_data.get("team", {}).get("id", None)
|
|
240
|
+
|
|
241
|
+
if not team_id:
|
|
242
|
+
raise ValueError("team_id is required.")
|
|
243
|
+
|
|
244
|
+
rest_client = TeamsInfo._get_rest_client(context)
|
|
245
|
+
return await rest_client.fetch_channel_list(team_id)
|
|
246
|
+
|
|
247
|
+
@staticmethod
|
|
248
|
+
async def get_paged_members(
|
|
249
|
+
context: TurnContext,
|
|
250
|
+
page_size: Optional[int] = None,
|
|
251
|
+
continuation_token: Optional[str] = None,
|
|
252
|
+
) -> TeamsPagedMembersResult:
|
|
253
|
+
"""
|
|
254
|
+
Gets the paged members of a team or conversation.
|
|
255
|
+
|
|
256
|
+
Args:
|
|
257
|
+
context: The turn context.
|
|
258
|
+
page_size: The page size.
|
|
259
|
+
continuation_token: The continuation token.
|
|
260
|
+
|
|
261
|
+
Returns:
|
|
262
|
+
The paged members result.
|
|
263
|
+
|
|
264
|
+
Raises:
|
|
265
|
+
ValueError: If required parameters are missing.
|
|
266
|
+
"""
|
|
267
|
+
teams_channel_data: dict = context.activity.channel_data
|
|
268
|
+
team_id = teams_channel_data.get("team", {}).get("id", None)
|
|
269
|
+
|
|
270
|
+
if team_id:
|
|
271
|
+
return await TeamsInfo.get_paged_team_members(
|
|
272
|
+
context, team_id, page_size, continuation_token
|
|
273
|
+
)
|
|
274
|
+
else:
|
|
275
|
+
conversation_id = (
|
|
276
|
+
context.activity.conversation.id
|
|
277
|
+
if context.activity.conversation
|
|
278
|
+
else None
|
|
279
|
+
)
|
|
280
|
+
if not conversation_id:
|
|
281
|
+
raise ValueError("conversation_id is required.")
|
|
282
|
+
|
|
283
|
+
rest_client = TeamsInfo._get_rest_client(context)
|
|
284
|
+
return await rest_client.get_conversation_paged_member(
|
|
285
|
+
conversation_id, page_size, continuation_token
|
|
286
|
+
)
|
|
287
|
+
|
|
288
|
+
@staticmethod
|
|
289
|
+
async def get_member(context: TurnContext, user_id: str) -> TeamsChannelAccount:
|
|
290
|
+
"""
|
|
291
|
+
Gets a member of a team or conversation.
|
|
292
|
+
|
|
293
|
+
Args:
|
|
294
|
+
context: The turn context.
|
|
295
|
+
user_id: The user ID.
|
|
296
|
+
|
|
297
|
+
Returns:
|
|
298
|
+
The member information.
|
|
299
|
+
|
|
300
|
+
Raises:
|
|
301
|
+
ValueError: If required parameters are missing.
|
|
302
|
+
"""
|
|
303
|
+
teams_channel_data: dict = context.activity.channel_data
|
|
304
|
+
team_id = teams_channel_data.get("team", {}).get("id", None)
|
|
305
|
+
|
|
306
|
+
if team_id:
|
|
307
|
+
return await TeamsInfo.get_team_member(context, team_id, user_id)
|
|
308
|
+
else:
|
|
309
|
+
conversation_id = (
|
|
310
|
+
context.activity.conversation.id
|
|
311
|
+
if context.activity.conversation
|
|
312
|
+
else None
|
|
313
|
+
)
|
|
314
|
+
if not conversation_id:
|
|
315
|
+
raise ValueError("conversation_id is required.")
|
|
316
|
+
|
|
317
|
+
return await TeamsInfo._get_member_internal(
|
|
318
|
+
context, conversation_id, user_id
|
|
319
|
+
)
|
|
320
|
+
|
|
321
|
+
@staticmethod
|
|
322
|
+
async def get_paged_team_members(
|
|
323
|
+
context: TurnContext,
|
|
324
|
+
team_id: Optional[str] = None,
|
|
325
|
+
page_size: Optional[int] = None,
|
|
326
|
+
continuation_token: Optional[str] = None,
|
|
327
|
+
) -> TeamsPagedMembersResult:
|
|
328
|
+
"""
|
|
329
|
+
Gets the paged members of a team.
|
|
330
|
+
|
|
331
|
+
Args:
|
|
332
|
+
context: The turn context.
|
|
333
|
+
team_id: The team ID. If not provided, it will be extracted from the activity.
|
|
334
|
+
page_size: The page size.
|
|
335
|
+
continuation_token: The continuation token.
|
|
336
|
+
|
|
337
|
+
Returns:
|
|
338
|
+
The paged members result.
|
|
339
|
+
|
|
340
|
+
Raises:
|
|
341
|
+
ValueError: If required parameters are missing.
|
|
342
|
+
"""
|
|
343
|
+
if not team_id:
|
|
344
|
+
teams_channel_data: dict = context.activity.channel_data
|
|
345
|
+
team_id = teams_channel_data.get("team", {}).get("id", None)
|
|
346
|
+
|
|
347
|
+
if not team_id:
|
|
348
|
+
raise ValueError("team_id is required.")
|
|
349
|
+
|
|
350
|
+
rest_client = TeamsInfo._get_rest_client(context)
|
|
351
|
+
paged_results = await rest_client.get_conversation_paged_member(
|
|
352
|
+
team_id, page_size, continuation_token
|
|
353
|
+
)
|
|
354
|
+
|
|
355
|
+
# Fetch all pages if there are more
|
|
356
|
+
while paged_results.continuation_token:
|
|
357
|
+
next_results = await rest_client.get_conversation_paged_member(
|
|
358
|
+
team_id, page_size, paged_results.continuation_token
|
|
359
|
+
)
|
|
360
|
+
paged_results.members.extend(next_results.members)
|
|
361
|
+
paged_results.continuation_token = next_results.continuation_token
|
|
362
|
+
|
|
363
|
+
return paged_results
|
|
364
|
+
|
|
365
|
+
@staticmethod
|
|
366
|
+
async def get_team_member(
|
|
367
|
+
context: TurnContext, team_id: str, user_id: str
|
|
368
|
+
) -> TeamsChannelAccount:
|
|
369
|
+
"""
|
|
370
|
+
Gets a member of a team.
|
|
371
|
+
|
|
372
|
+
Args:
|
|
373
|
+
context: The turn context.
|
|
374
|
+
team_id: The team ID.
|
|
375
|
+
user_id: The user ID.
|
|
376
|
+
|
|
377
|
+
Returns:
|
|
378
|
+
The member information.
|
|
379
|
+
|
|
380
|
+
Raises:
|
|
381
|
+
ValueError: If required parameters are missing.
|
|
382
|
+
"""
|
|
383
|
+
rest_client = TeamsInfo._get_rest_client(context)
|
|
384
|
+
return await rest_client.get_conversation_member(team_id, user_id)
|
|
385
|
+
|
|
386
|
+
@staticmethod
|
|
387
|
+
async def send_meeting_notification(
|
|
388
|
+
context: TurnContext,
|
|
389
|
+
notification: MeetingNotification,
|
|
390
|
+
meeting_id: Optional[str] = None,
|
|
391
|
+
) -> MeetingNotificationResponse:
|
|
392
|
+
"""
|
|
393
|
+
Sends a meeting notification.
|
|
394
|
+
|
|
395
|
+
Args:
|
|
396
|
+
context: The turn context.
|
|
397
|
+
notification: The meeting notification.
|
|
398
|
+
meeting_id: The meeting ID. If not provided, it will be extracted from the activity.
|
|
399
|
+
|
|
400
|
+
Returns:
|
|
401
|
+
The meeting notification response.
|
|
402
|
+
|
|
403
|
+
Raises:
|
|
404
|
+
ValueError: If required parameters are missing.
|
|
405
|
+
"""
|
|
406
|
+
activity = context.activity
|
|
407
|
+
|
|
408
|
+
if meeting_id is None:
|
|
409
|
+
teams_channel_data: dict = activity.channel_data
|
|
410
|
+
meeting_id = teams_channel_data.get("meeting", {}).get("id", None)
|
|
411
|
+
|
|
412
|
+
if not meeting_id:
|
|
413
|
+
raise ValueError("meeting_id is required.")
|
|
414
|
+
|
|
415
|
+
rest_client = TeamsInfo._get_rest_client(context)
|
|
416
|
+
return await rest_client.send_meeting_notification(meeting_id, notification)
|
|
417
|
+
|
|
418
|
+
@staticmethod
|
|
419
|
+
async def send_message_to_list_of_users(
|
|
420
|
+
context: TurnContext,
|
|
421
|
+
activity: Activity,
|
|
422
|
+
tenant_id: str,
|
|
423
|
+
members: List[TeamsMember],
|
|
424
|
+
) -> TeamsBatchOperationResponse:
|
|
425
|
+
"""
|
|
426
|
+
Sends a message to a list of users.
|
|
427
|
+
|
|
428
|
+
Args:
|
|
429
|
+
context: The turn context.
|
|
430
|
+
activity: The activity to send.
|
|
431
|
+
tenant_id: The tenant ID.
|
|
432
|
+
members: The list of members.
|
|
433
|
+
|
|
434
|
+
Returns:
|
|
435
|
+
The batch operation response.
|
|
436
|
+
|
|
437
|
+
Raises:
|
|
438
|
+
ValueError: If required parameters are missing.
|
|
439
|
+
"""
|
|
440
|
+
if not activity:
|
|
441
|
+
raise ValueError("activity is required.")
|
|
442
|
+
if not tenant_id:
|
|
443
|
+
raise ValueError("tenant_id is required.")
|
|
444
|
+
if not members or len(members) == 0:
|
|
445
|
+
raise ValueError("members list is required.")
|
|
446
|
+
|
|
447
|
+
rest_client = TeamsInfo._get_rest_client(context)
|
|
448
|
+
return await rest_client.send_message_to_list_of_users(
|
|
449
|
+
activity, tenant_id, members
|
|
450
|
+
)
|
|
451
|
+
|
|
452
|
+
@staticmethod
|
|
453
|
+
async def send_message_to_all_users_in_tenant(
|
|
454
|
+
context: TurnContext, activity: Activity, tenant_id: str
|
|
455
|
+
) -> TeamsBatchOperationResponse:
|
|
456
|
+
"""
|
|
457
|
+
Sends a message to all users in a tenant.
|
|
458
|
+
|
|
459
|
+
Args:
|
|
460
|
+
context: The turn context.
|
|
461
|
+
activity: The activity to send.
|
|
462
|
+
tenant_id: The tenant ID.
|
|
463
|
+
|
|
464
|
+
Returns:
|
|
465
|
+
The batch operation response.
|
|
466
|
+
|
|
467
|
+
Raises:
|
|
468
|
+
ValueError: If required parameters are missing.
|
|
469
|
+
"""
|
|
470
|
+
if not activity:
|
|
471
|
+
raise ValueError("activity is required.")
|
|
472
|
+
if not tenant_id:
|
|
473
|
+
raise ValueError("tenant_id is required.")
|
|
474
|
+
|
|
475
|
+
rest_client = TeamsInfo._get_rest_client(context)
|
|
476
|
+
return await rest_client.send_message_to_all_users_in_tenant(
|
|
477
|
+
activity, tenant_id
|
|
478
|
+
)
|
|
479
|
+
|
|
480
|
+
@staticmethod
|
|
481
|
+
async def send_message_to_all_users_in_team(
|
|
482
|
+
context: TurnContext, activity: Activity, tenant_id: str, team_id: str
|
|
483
|
+
) -> TeamsBatchOperationResponse:
|
|
484
|
+
"""
|
|
485
|
+
Sends a message to all users in a team.
|
|
486
|
+
|
|
487
|
+
Args:
|
|
488
|
+
context: The turn context.
|
|
489
|
+
activity: The activity to send.
|
|
490
|
+
tenant_id: The tenant ID.
|
|
491
|
+
team_id: The team ID.
|
|
492
|
+
|
|
493
|
+
Returns:
|
|
494
|
+
The batch operation response.
|
|
495
|
+
|
|
496
|
+
Raises:
|
|
497
|
+
ValueError: If required parameters are missing.
|
|
498
|
+
"""
|
|
499
|
+
if not activity:
|
|
500
|
+
raise ValueError("activity is required.")
|
|
501
|
+
if not tenant_id:
|
|
502
|
+
raise ValueError("tenant_id is required.")
|
|
503
|
+
if not team_id:
|
|
504
|
+
raise ValueError("team_id is required.")
|
|
505
|
+
|
|
506
|
+
rest_client = TeamsInfo._get_rest_client(context)
|
|
507
|
+
return await rest_client.send_message_to_all_users_in_team(
|
|
508
|
+
activity, tenant_id, team_id
|
|
509
|
+
)
|
|
510
|
+
|
|
511
|
+
@staticmethod
|
|
512
|
+
async def send_message_to_list_of_channels(
|
|
513
|
+
context: TurnContext,
|
|
514
|
+
activity: Activity,
|
|
515
|
+
tenant_id: str,
|
|
516
|
+
members: List[TeamsMember],
|
|
517
|
+
) -> TeamsBatchOperationResponse:
|
|
518
|
+
"""
|
|
519
|
+
Sends a message to a list of channels.
|
|
520
|
+
|
|
521
|
+
Args:
|
|
522
|
+
context: The turn context.
|
|
523
|
+
activity: The activity to send.
|
|
524
|
+
tenant_id: The tenant ID.
|
|
525
|
+
members: The list of members.
|
|
526
|
+
|
|
527
|
+
Returns:
|
|
528
|
+
The batch operation response.
|
|
529
|
+
|
|
530
|
+
Raises:
|
|
531
|
+
ValueError: If required parameters are missing.
|
|
532
|
+
"""
|
|
533
|
+
if not activity:
|
|
534
|
+
raise ValueError("activity is required.")
|
|
535
|
+
if not tenant_id:
|
|
536
|
+
raise ValueError("tenant_id is required.")
|
|
537
|
+
if not members or len(members) == 0:
|
|
538
|
+
raise ValueError("members list is required.")
|
|
539
|
+
|
|
540
|
+
rest_client = TeamsInfo._get_rest_client(context)
|
|
541
|
+
return await rest_client.send_message_to_list_of_channels(
|
|
542
|
+
activity, tenant_id, members
|
|
543
|
+
)
|
|
544
|
+
|
|
545
|
+
@staticmethod
|
|
546
|
+
async def get_operation_state(
|
|
547
|
+
context: TurnContext, operation_id: str
|
|
548
|
+
) -> BatchOperationStateResponse:
|
|
549
|
+
"""
|
|
550
|
+
Gets the operation state.
|
|
551
|
+
|
|
552
|
+
Args:
|
|
553
|
+
context: The turn context.
|
|
554
|
+
operation_id: The operation ID.
|
|
555
|
+
|
|
556
|
+
Returns:
|
|
557
|
+
The operation state response.
|
|
558
|
+
|
|
559
|
+
Raises:
|
|
560
|
+
ValueError: If required parameters are missing.
|
|
561
|
+
"""
|
|
562
|
+
if not operation_id:
|
|
563
|
+
raise ValueError("operation_id is required.")
|
|
564
|
+
|
|
565
|
+
rest_client = TeamsInfo._get_rest_client(context)
|
|
566
|
+
return await rest_client.get_operation_state(operation_id)
|
|
567
|
+
|
|
568
|
+
@staticmethod
|
|
569
|
+
async def get_failed_entries(
|
|
570
|
+
context: TurnContext, operation_id: str
|
|
571
|
+
) -> BatchFailedEntriesResponse:
|
|
572
|
+
"""
|
|
573
|
+
Gets the failed entries of an operation.
|
|
574
|
+
|
|
575
|
+
Args:
|
|
576
|
+
context: The turn context.
|
|
577
|
+
operation_id: The operation ID.
|
|
578
|
+
|
|
579
|
+
Returns:
|
|
580
|
+
The failed entries response.
|
|
581
|
+
|
|
582
|
+
Raises:
|
|
583
|
+
ValueError: If required parameters are missing.
|
|
584
|
+
"""
|
|
585
|
+
if not operation_id:
|
|
586
|
+
raise ValueError("operation_id is required.")
|
|
587
|
+
|
|
588
|
+
rest_client = TeamsInfo._get_rest_client(context)
|
|
589
|
+
return await rest_client.get_failed_entries(operation_id)
|
|
590
|
+
|
|
591
|
+
@staticmethod
|
|
592
|
+
async def cancel_operation(
|
|
593
|
+
context: TurnContext, operation_id: str
|
|
594
|
+
) -> CancelOperationResponse:
|
|
595
|
+
"""
|
|
596
|
+
Cancels an operation.
|
|
597
|
+
|
|
598
|
+
Args:
|
|
599
|
+
context: The turn context.
|
|
600
|
+
operation_id: The operation ID.
|
|
601
|
+
|
|
602
|
+
Returns:
|
|
603
|
+
The cancel operation response.
|
|
604
|
+
|
|
605
|
+
Raises:
|
|
606
|
+
ValueError: If required parameters are missing.
|
|
607
|
+
"""
|
|
608
|
+
if not operation_id:
|
|
609
|
+
raise ValueError("operation_id is required.")
|
|
610
|
+
|
|
611
|
+
rest_client = TeamsInfo._get_rest_client(context)
|
|
612
|
+
return await rest_client.cancel_operation(operation_id)
|
|
613
|
+
|
|
614
|
+
@staticmethod
|
|
615
|
+
async def _get_member_internal(
|
|
616
|
+
context: TurnContext, conversation_id: str, user_id: str
|
|
617
|
+
) -> TeamsChannelAccount:
|
|
618
|
+
"""
|
|
619
|
+
Internal method to get a member from a conversation.
|
|
620
|
+
|
|
621
|
+
Args:
|
|
622
|
+
context: The turn context.
|
|
623
|
+
conversation_id: The conversation ID.
|
|
624
|
+
user_id: The user ID.
|
|
625
|
+
|
|
626
|
+
Returns:
|
|
627
|
+
The member information.
|
|
628
|
+
|
|
629
|
+
Raises:
|
|
630
|
+
ValueError: If required parameters are missing.
|
|
631
|
+
"""
|
|
632
|
+
rest_client = TeamsInfo._get_rest_client(context)
|
|
633
|
+
return await rest_client.get_conversation_member(conversation_id, user_id)
|
|
634
|
+
|
|
635
|
+
@staticmethod
|
|
636
|
+
def _get_rest_client(context: TurnContext) -> TeamsConnectorClient:
|
|
637
|
+
"""
|
|
638
|
+
Gets the Teams connector client from the context.
|
|
639
|
+
|
|
640
|
+
Args:
|
|
641
|
+
context: The turn context.
|
|
642
|
+
|
|
643
|
+
Returns:
|
|
644
|
+
The Teams connector client.
|
|
645
|
+
|
|
646
|
+
Raises:
|
|
647
|
+
ValueError: If the client is not available in the context.
|
|
648
|
+
"""
|
|
649
|
+
# TODO: Varify key
|
|
650
|
+
client = context.turn_state.get("ConnectorClient")
|
|
651
|
+
if not client:
|
|
652
|
+
raise ValueError("TeamsConnectorClient is not available in the context.")
|
|
653
|
+
return client
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: microsoft-agents-hosting-teams
|
|
3
|
+
Version: 0.0.0
|
|
4
|
+
Summary: Integration library for Microsoft Agents with Teams
|
|
5
|
+
Author: Microsoft Corporation
|
|
6
|
+
Project-URL: Homepage, https://github.com/microsoft/Agents
|
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
9
|
+
Classifier: Operating System :: OS Independent
|
|
10
|
+
Requires-Python: >=3.9
|
|
11
|
+
Requires-Dist: microsoft-agents-hosting-core==0.0.0
|
|
12
|
+
Requires-Dist: aiohttp>=3.11.11
|
|
13
|
+
Dynamic: requires-dist
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
microsoft/agents/hosting/teams/__init__.py,sha256=dFygIL_ogurLI5uq9ikd5C-MZl7uXVw5rUVfi1_H5jY,140
|
|
2
|
+
microsoft/agents/hosting/teams/teams_activity_handler.py,sha256=OVutqeBNgcJJaO3uZarbP-cNg5vxUOlYLJ8VRuriOc0,32762
|
|
3
|
+
microsoft/agents/hosting/teams/teams_cloud_adapter.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
+
microsoft/agents/hosting/teams/teams_info.py,sha256=lj7OhfxNsYBry2J4286jyK_Q7GMGo8dVRrcDVP7JvoI,20756
|
|
5
|
+
microsoft_agents_hosting_teams-0.0.0.dist-info/METADATA,sha256=QRqQLoNdDggCHRB0Yc_XTQyvPzZKaK7tFY9lZfHceJY,500
|
|
6
|
+
microsoft_agents_hosting_teams-0.0.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
7
|
+
microsoft_agents_hosting_teams-0.0.0.dist-info/top_level.txt,sha256=egwWDmpnNBTGerc55Oa6VVW9hTKdtxFjHWHywqmVMpM,10
|
|
8
|
+
microsoft_agents_hosting_teams-0.0.0.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
microsoft
|