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

Commit 4e0af9d

Browse files
authored
Merge branch 'main' into dependabot/pip/libraries/botbuilder-core/pip-27b05608f7
2 parents 129234e + ac28ca3 commit 4e0af9d

File tree

21 files changed

+159
-25
lines changed

21 files changed

+159
-25
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ We use the [@msbotframework](https://twitter.com/msbotframework) account on twit
118118
The [Gitter Channel](https://gitter.im/Microsoft/BotBuilder) provides a place where the Community can get together and collaborate.
119119

120120
## Contributing and our code of conduct
121-
We welcome contributions and suggestions. Please see our [contributing guidelines](./contributing.md) for more information.
121+
We welcome contributions and suggestions. Please see our [contributing guidelines](./Contributing.md) for more information.
122122

123123
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
124124

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
aiohttp==3.10.11
1+
aiohttp
22
pyslack
33
botbuilder-core==4.17.0
44
slackclient

libraries/botbuilder-ai/setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"azure-cognitiveservices-language-luis==0.2.0",
99
"botbuilder-schema==4.17.0",
1010
"botbuilder-core==4.17.0",
11-
"aiohttp==3.10.11",
11+
"aiohttp>=3.10,<4.0",
1212
]
1313

1414
TESTS_REQUIRES = ["aiounittest>=1.1.0"]

libraries/botbuilder-core/botbuilder/core/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
from .user_state import UserState
4949
from .register_class_middleware import RegisterClassMiddleware
5050
from .adapter_extensions import AdapterExtensions
51+
from .serializer_helper import serializer_helper
5152

5253
__all__ = [
5354
"ActivityHandler",
@@ -100,5 +101,6 @@
100101
"TurnContext",
101102
"UserState",
102103
"UserTokenProvider",
104+
"serializer_helper",
103105
"__version__",
104106
]

libraries/botbuilder-core/botbuilder/core/activity_handler.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -478,12 +478,19 @@ async def on_invoke_activity( # pylint: disable=unused-argument
478478
if (
479479
turn_context.activity.name
480480
== SignInConstants.verify_state_operation_name
481-
or turn_context.activity.name
482-
== SignInConstants.token_exchange_operation_name
483481
):
484482
await self.on_sign_in_invoke(turn_context)
485483
return self._create_invoke_response()
486484

485+
# This is for back-compat with previous versions of Python SDK. This method does not
486+
# exist in the C# SDK, and is not used in the Python SDK.
487+
if (
488+
turn_context.activity.name
489+
== SignInConstants.token_exchange_operation_name
490+
):
491+
await self.on_teams_signin_token_exchange(turn_context)
492+
return self._create_invoke_response()
493+
487494
if turn_context.activity.name == "adaptiveCard/action":
488495
invoke_value = self._get_adaptive_card_invoke_value(
489496
turn_context.activity

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

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,6 @@ async def on_invoke_activity(self, turn_context: TurnContext) -> InvokeResponse:
5656
):
5757
return await self.on_teams_card_action_invoke(turn_context)
5858

59-
if (
60-
turn_context.activity.name
61-
== SignInConstants.token_exchange_operation_name
62-
):
63-
await self.on_teams_signin_token_exchange(turn_context)
64-
return self._create_invoke_response()
65-
6659
if turn_context.activity.name == "fileConsent/invoke":
6760
return await self.on_teams_file_consent(
6861
turn_context,
@@ -250,7 +243,9 @@ async def on_teams_signin_verify_state(self, turn_context: TurnContext):
250243
raise _InvokeResponseException(status_code=HTTPStatus.NOT_IMPLEMENTED)
251244

252245
async def on_teams_signin_token_exchange(self, turn_context: TurnContext):
253-
raise _InvokeResponseException(status_code=HTTPStatus.NOT_IMPLEMENTED)
246+
# This is for back-compat with previous versions of Python SDK. This method does not
247+
# exist in the C# SDK, and is not used in the Python SDK.
248+
return await self.on_teams_signin_verify_state(turn_context)
254249

255250
async def on_teams_file_consent(
256251
self,

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

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
StoreItem,
2727
TurnContext,
2828
)
29+
from botframework.connector.auth.user_token_client import UserTokenClient
2930

3031

3132
class _TokenStoreItem(StoreItem):
@@ -147,17 +148,29 @@ async def _exchanged_token(self, turn_context: TurnContext) -> bool:
147148
token_exchange_response: TokenResponse = None
148149
aux_dict = {}
149150
if turn_context.activity.value:
150-
for prop in ["id", "connection_name", "token", "properties"]:
151+
for prop in ["id", "connectionName", "token", "properties"]:
151152
aux_dict[prop] = turn_context.activity.value.get(prop)
152153
token_exchange_request = TokenExchangeInvokeRequest(
153154
id=aux_dict["id"],
154-
connection_name=aux_dict["connection_name"],
155+
connection_name=aux_dict["connectionName"],
155156
token=aux_dict["token"],
156157
properties=aux_dict["properties"],
157158
)
158159
try:
159160
adapter = turn_context.adapter
160-
if isinstance(turn_context.adapter, ExtendedUserTokenProvider):
161+
162+
user_token_client: UserTokenClient = turn_context.turn_state.get(
163+
UserTokenClient.__name__, None
164+
)
165+
if user_token_client:
166+
# If the adapter has UserTokenClient, use it to exchange the token.
167+
token_exchange_response = await user_token_client.exchange_token(
168+
turn_context.activity.from_property.id,
169+
token_exchange_request.connection_name,
170+
turn_context.activity.channel_id,
171+
TokenExchangeRequest(token=token_exchange_request.token),
172+
)
173+
elif isinstance(turn_context.adapter, ExtendedUserTokenProvider):
161174
token_exchange_response = await adapter.exchange_token(
162175
turn_context,
163176
self._oauth_connection_name,

libraries/botbuilder-core/botbuilder/core/turn_context.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -396,9 +396,13 @@ def remove_mention_text(activity: Activity, identifier: str) -> str:
396396
mentions = TurnContext.get_mentions(activity)
397397
for mention in mentions:
398398
if mention.additional_properties["mentioned"]["id"] == identifier:
399+
replace_text = (
400+
mention.additional_properties.get("text")
401+
or mention.additional_properties.get("mentioned")["name"]
402+
)
399403
mention_name_match = re.match(
400404
r"<at(.*)>(.*?)<\/at>",
401-
escape(mention.additional_properties["text"]),
405+
escape(replace_text),
402406
re.IGNORECASE,
403407
)
404408
if mention_name_match:

libraries/botbuilder-core/tests/test_turn_context.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,48 @@ def test_should_remove_at_mention_with_regex_characters(self):
350350
assert text == " test activity"
351351
assert activity.text == " test activity"
352352

353+
def test_should_remove_custom_mention_from_activity(self):
354+
activity = Activity(
355+
text="Hallo",
356+
text_format="plain",
357+
type="message",
358+
timestamp="2025-03-11T14:16:47.0093935Z",
359+
id="1741702606984",
360+
channel_id="msteams",
361+
service_url="https://smba.trafficmanager.net/emea/REDACTED/",
362+
from_property=ChannelAccount(
363+
id="29:1J-K4xVh-sLpdwQ-R5GkOZ_TB0W3ec_37p710aH8qe8bITA0zxdgIGc9l-MdDdkdE_jasSfNOeWXyyL1nsrHtBQ",
364+
name="",
365+
aad_object_id="REDACTED",
366+
),
367+
conversation=ConversationAccount(
368+
is_group=True,
369+
conversation_type="groupChat",
370+
tenant_id="REDACTED",
371+
id="19:Ql86tXNM2lTBXNKJdqKdwIF9ltGZwpvluLvnJdA0tmg1@thread.v2",
372+
),
373+
recipient=ChannelAccount(
374+
id="28:c5d5fb56-a1a4-4467-a7a3-1b37905498a0", name="Azure AI Agent"
375+
),
376+
entities=[
377+
Entity().deserialize(
378+
Mention(
379+
type="mention",
380+
mentioned=ChannelAccount(
381+
id="28:c5d5fb56-a1a4-4467-a7a3-1b37905498a0",
382+
name="Custom Agent",
383+
),
384+
).serialize()
385+
)
386+
],
387+
channel_data={"tenant": {"id": "REDACTED"}, "productContext": "COPILOT"},
388+
)
389+
390+
text = TurnContext.remove_mention_text(activity, activity.recipient.id)
391+
392+
assert text == "Hallo"
393+
assert activity.text == "Hallo"
394+
353395
async def test_should_send_a_trace_activity(self):
354396
context = TurnContext(SimpleAdapter(), ACTIVITY)
355397
called = False

libraries/botbuilder-dialogs/botbuilder/dialogs/dialog.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ async def on_dialog_event(
125125

126126
# Bubble as needed
127127
if (not handled) and dialog_event.bubble and dialog_context.parent:
128-
handled = await dialog_context.parent.emit(
128+
handled = await dialog_context.parent.emit_event(
129129
dialog_event.name, dialog_event.value, True, False
130130
)
131131

0 commit comments

Comments
 (0)