Skip to content
This repository was archived by the owner on Jan 5, 2026. It is now read-only.

Commit a8d3029

Browse files
committed
Merge branch 'eric/teams_info' of https://github.com/microsoft/botbuilder-python into eric/teams_info
2 parents 79b9ab9 + 96077a8 commit a8d3029

File tree

6 files changed

+836
-78
lines changed

6 files changed

+836
-78
lines changed

libraries/botbuilder-core/botbuilder/core/teams/teams_activity_handler.py

Lines changed: 58 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,16 @@
66
from botbuilder.core.turn_context import TurnContext
77
from botbuilder.core import ActivityHandler, InvokeResponse, BotFrameworkAdapter
88
from botbuilder.schema.teams import (
9+
AppBasedLinkQuery,
910
TeamInfo,
1011
ChannelInfo,
12+
FileConsentCardResponse,
1113
TeamsChannelData,
1214
TeamsChannelAccount,
15+
MessagingExtensionAction,
16+
MessagingExtensionQuery,
17+
O365ConnectorCardActionQuery,
18+
TaskModuleRequest,
1319
)
1420
from botframework.connector import Channels
1521

@@ -55,26 +61,28 @@ async def on_invoke_activity(self, turn_context: TurnContext):
5561

5662
if turn_context.activity.name == "fileConsent/invoke":
5763
return await self.on_teams_file_consent(
58-
turn_context, turn_context.activity.value
64+
turn_context, FileConsentCardResponse(**turn_context.activity.value)
5965
)
6066

6167
if turn_context.activity.name == "actionableMessage/executeAction":
6268
await self.on_teams_o365_connector_card_action(
63-
turn_context, turn_context.activity.value
69+
turn_context,
70+
O365ConnectorCardActionQuery(**turn_context.activity.value),
6471
)
6572
return self._create_invoke_response()
6673

6774
if turn_context.activity.name == "composeExtension/queryLink":
6875
return self._create_invoke_response(
6976
await self.on_teams_app_based_link_query(
70-
turn_context, turn_context.activity.value
77+
turn_context, AppBasedLinkQuery(**turn_context.activity.value)
7178
)
7279
)
7380

7481
if turn_context.activity.name == "composeExtension/query":
7582
return self._create_invoke_response(
7683
await self.on_teams_messaging_extension_query(
77-
turn_context, turn_context.activity.value
84+
turn_context,
85+
MessagingExtensionQuery(**turn_context.activity.value),
7886
)
7987
)
8088

@@ -88,21 +96,24 @@ async def on_invoke_activity(self, turn_context: TurnContext):
8896
if turn_context.activity.name == "composeExtension/submitAction":
8997
return self._create_invoke_response(
9098
await self.on_teams_messaging_extension_submit_action_dispatch(
91-
turn_context, turn_context.activity.value
99+
turn_context,
100+
MessagingExtensionAction(**turn_context.activity.value),
92101
)
93102
)
94103

95104
if turn_context.activity.name == "composeExtension/fetchTask":
96105
return self._create_invoke_response(
97106
await self.on_teams_messaging_extension_fetch_task(
98-
turn_context, turn_context.activity.value
107+
turn_context,
108+
MessagingExtensionAction(**turn_context.activity.value),
99109
)
100110
)
101111

102112
if turn_context.activity.name == "composeExtension/querySettingUrl":
103113
return self._create_invoke_response(
104114
await self.on_teams_messaging_extension_configuration_query_settings_url(
105-
turn_context, turn_context.activity.value
115+
turn_context,
116+
MessagingExtensionQuery(**turn_context.activity.value),
106117
)
107118
)
108119

@@ -121,14 +132,14 @@ async def on_invoke_activity(self, turn_context: TurnContext):
121132
if turn_context.activity.name == "task/fetch":
122133
return self._create_invoke_response(
123134
await self.on_teams_task_module_fetch(
124-
turn_context, turn_context.activity.value
135+
turn_context, TaskModuleRequest(**turn_context.activity.value)
125136
)
126137
)
127138

128139
if turn_context.activity.name == "task/submit":
129140
return self._create_invoke_response(
130141
await self.on_teams_task_module_submit(
131-
turn_context, turn_context.activity.value
142+
turn_context, TaskModuleRequest(**turn_context.activity.value)
132143
)
133144
)
134145

@@ -143,7 +154,9 @@ async def on_teams_signin_verify_state(self, turn_context: TurnContext):
143154
raise _InvokeResponseException(status_code=HTTPStatus.NOT_IMPLEMENTED)
144155

145156
async def on_teams_file_consent(
146-
self, turn_context: TurnContext, file_consent_card_response
157+
self,
158+
turn_context: TurnContext,
159+
file_consent_card_response: FileConsentCardResponse,
147160
):
148161
if file_consent_card_response.action == "accept":
149162
await self.on_teams_file_consent_accept_activity(
@@ -163,27 +176,31 @@ async def on_teams_file_consent(
163176
)
164177

165178
async def on_teams_file_consent_accept_activity( # pylint: disable=unused-argument
166-
self, turn_context: TurnContext, file_consent_card_response
179+
self,
180+
turn_context: TurnContext,
181+
file_consent_card_response: FileConsentCardResponse,
167182
):
168183
raise _InvokeResponseException(status_code=HTTPStatus.NOT_IMPLEMENTED)
169184

170185
async def on_teams_file_consent_decline_activity( # pylint: disable=unused-argument
171-
self, turn_context: TurnContext, file_consent_card_response
186+
self,
187+
turn_context: TurnContext,
188+
file_consent_card_response: FileConsentCardResponse,
172189
):
173190
raise _InvokeResponseException(status_code=HTTPStatus.NOT_IMPLEMENTED)
174191

175192
async def on_teams_o365_connector_card_action( # pylint: disable=unused-argument
176-
self, turn_context: TurnContext, query
193+
self, turn_context: TurnContext, query: O365ConnectorCardActionQuery
177194
):
178195
raise _InvokeResponseException(status_code=HTTPStatus.NOT_IMPLEMENTED)
179196

180197
async def on_teams_app_based_link_query( # pylint: disable=unused-argument
181-
self, turn_context: TurnContext, query
198+
self, turn_context: TurnContext, query: AppBasedLinkQuery
182199
):
183200
raise _InvokeResponseException(status_code=HTTPStatus.NOT_IMPLEMENTED)
184201

185202
async def on_teams_messaging_extension_query( # pylint: disable=unused-argument
186-
self, turn_context: TurnContext, query
203+
self, turn_context: TurnContext, query: MessagingExtensionQuery
187204
):
188205
raise _InvokeResponseException(status_code=HTTPStatus.NOT_IMPLEMENTED)
189206

@@ -193,9 +210,9 @@ async def on_teams_messaging_extension_select_item( # pylint: disable=unused-ar
193210
raise _InvokeResponseException(status_code=HTTPStatus.NOT_IMPLEMENTED)
194211

195212
async def on_teams_messaging_extension_submit_action_dispatch(
196-
self, turn_context: TurnContext, action
213+
self, turn_context: TurnContext, action: MessagingExtensionAction
197214
):
198-
if not action:
215+
if not action.bot_message_preview_action:
199216
return await self.on_teams_messaging_extension_submit_action_activity(
200217
turn_context, action
201218
)
@@ -226,17 +243,17 @@ async def on_teams_messaging_extension_bot_message_send_activity( # pylint: dis
226243
raise _InvokeResponseException(status_code=HTTPStatus.NOT_IMPLEMENTED)
227244

228245
async def on_teams_messaging_extension_submit_action_activity( # pylint: disable=unused-argument
229-
self, turn_context: TurnContext, action
246+
self, turn_context: TurnContext, action: MessagingExtensionAction
230247
):
231248
raise _InvokeResponseException(status_code=HTTPStatus.NOT_IMPLEMENTED)
232249

233250
async def on_teams_messaging_extension_fetch_task( # pylint: disable=unused-argument
234-
self, turn_context: TurnContext, task_module_request
251+
self, turn_context: TurnContext, action: MessagingExtensionAction
235252
):
236253
raise _InvokeResponseException(status_code=HTTPStatus.NOT_IMPLEMENTED)
237254

238255
async def on_teams_messaging_extension_configuration_query_settings_url( # pylint: disable=unused-argument
239-
self, turn_context: TurnContext, query
256+
self, turn_context: TurnContext, query: MessagingExtensionQuery
240257
):
241258
raise _InvokeResponseException(status_code=HTTPStatus.NOT_IMPLEMENTED)
242259

@@ -251,19 +268,19 @@ async def on_teams_messaging_extension_card_button_clicked( # pylint: disable=u
251268
raise _InvokeResponseException(status_code=HTTPStatus.NOT_IMPLEMENTED)
252269

253270
async def on_teams_task_module_fetch( # pylint: disable=unused-argument
254-
self, turn_context: TurnContext, task_module_request
271+
self, turn_context: TurnContext, task_module_request: TaskModuleRequest
255272
):
256273
raise _InvokeResponseException(status_code=HTTPStatus.NOT_IMPLEMENTED)
257274

258275
async def on_teams_task_module_submit( # pylint: disable=unused-argument
259-
self, turn_context: TurnContext, task_module_request
276+
self, turn_context: TurnContext, task_module_request: TaskModuleRequest
260277
):
261278
raise _InvokeResponseException(status_code=HTTPStatus.NOT_IMPLEMENTED)
262279

263280
async def on_conversation_update_activity(self, turn_context: TurnContext):
281+
264282
if turn_context.activity.channel_id == Channels.ms_teams:
265283
channel_data = TeamsChannelData(**turn_context.activity.channel_data)
266-
267284
if turn_context.activity.members_added:
268285
return await self.on_teams_members_added_dispatch_activity(
269286
turn_context.activity.members_added, channel_data.team, turn_context
@@ -279,7 +296,9 @@ async def on_conversation_update_activity(self, turn_context: TurnContext):
279296
if channel_data:
280297
if channel_data.event_type == "channelCreated":
281298
return await self.on_teams_channel_created_activity(
282-
channel_data.channel, channel_data.team, turn_context
299+
ChannelInfo(**channel_data.channel),
300+
channel_data.team,
301+
turn_context,
283302
)
284303
if channel_data.event_type == "channelDeleted":
285304
return await self.on_teams_channel_deleted_activity(
@@ -337,19 +356,27 @@ async def on_teams_members_added_dispatch_activity( # pylint: disable=unused-ar
337356
338357
return await self.on_teams_members_added_activity(teams_members_added, team_info, turn_context)
339358
"""
359+
team_accounts_added = []
340360
for member in members_added:
341361
# TODO: fix this
342362
new_account_json = member.serialize()
343363
if "additional_properties" in new_account_json:
344364
del new_account_json["additional_properties"]
345365
member = TeamsChannelAccount(**new_account_json)
346-
return await self.on_teams_members_added_activity(members_added, turn_context)
366+
team_accounts_added.append(member)
367+
return await self.on_teams_members_added_activity(
368+
team_accounts_added, turn_context
369+
)
347370

348371
async def on_teams_members_added_activity(
349372
self, teams_members_added: [TeamsChannelAccount], turn_context: TurnContext
350373
):
351-
teams_members_added = [ChannelAccount(member) for member in teams_members_added]
352-
return super().on_members_added_activity(teams_members_added, turn_context)
374+
teams_members_added = [
375+
ChannelAccount(**member.serialize()) for member in teams_members_added
376+
]
377+
return await super().on_members_added_activity(
378+
teams_members_added, turn_context
379+
)
353380

354381
async def on_teams_members_removed_dispatch_activity( # pylint: disable=unused-argument
355382
self,
@@ -372,8 +399,10 @@ async def on_teams_members_removed_dispatch_activity( # pylint: disable=unused-
372399
async def on_teams_members_removed_activity(
373400
self, teams_members_removed: [TeamsChannelAccount], turn_context: TurnContext
374401
):
375-
members_removed = [ChannelAccount(member) for member in teams_members_removed]
376-
return super().on_members_removed_activity(members_removed, turn_context)
402+
members_removed = [
403+
ChannelAccount(**member.serialize()) for member in teams_members_removed
404+
]
405+
return await super().on_members_removed_activity(members_removed, turn_context)
377406

378407
async def on_teams_channel_deleted_activity( # pylint: disable=unused-argument
379408
self, channel_info: ChannelInfo, team_info: TeamInfo, turn_context: TurnContext
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# Copyright (c) Microsoft Corporation. All rights reserved.
2+
# Licensed under the MIT License.
3+
4+
import unittest
5+
from typing import List
6+
from botbuilder.core import BotAdapter, TurnContext
7+
from botbuilder.schema import Activity, ConversationReference, ResourceResponse
8+
9+
10+
class SimpleAdapter(BotAdapter):
11+
# pylint: disable=unused-argument
12+
13+
def __init__(self, call_on_send=None, call_on_update=None, call_on_delete=None):
14+
super(SimpleAdapter, self).__init__()
15+
self.test_aux = unittest.TestCase("__init__")
16+
self._call_on_send = call_on_send
17+
self._call_on_update = call_on_update
18+
self._call_on_delete = call_on_delete
19+
20+
async def delete_activity(
21+
self, context: TurnContext, reference: ConversationReference
22+
):
23+
self.test_aux.assertIsNotNone(
24+
reference, "SimpleAdapter.delete_activity: missing reference"
25+
)
26+
if self._call_on_delete is not None:
27+
self._call_on_delete(reference)
28+
29+
async def send_activities(
30+
self, context: TurnContext, activities: List[Activity]
31+
) -> List[ResourceResponse]:
32+
self.test_aux.assertIsNotNone(
33+
activities, "SimpleAdapter.delete_activity: missing reference"
34+
)
35+
self.test_aux.assertTrue(
36+
len(activities) > 0,
37+
"SimpleAdapter.send_activities: empty activities array.",
38+
)
39+
40+
if self._call_on_send is not None:
41+
self._call_on_send(activities)
42+
responses = []
43+
44+
for activity in activities:
45+
responses.append(ResourceResponse(id=activity.id))
46+
47+
return responses
48+
49+
async def update_activity(self, context: TurnContext, activity: Activity):
50+
self.test_aux.assertIsNotNone(
51+
activity, "SimpleAdapter.update_activity: missing activity"
52+
)
53+
if self._call_on_update is not None:
54+
self._call_on_update(activity)
55+
56+
return ResourceResponse(activity.id)
57+
58+
async def process_request(self, activity, handler):
59+
context = TurnContext(self, activity)
60+
return self.run_pipeline(context, handler)

0 commit comments

Comments
 (0)