8000 Add new Teams invoke types 'config/fetch' and 'config/submit' (#2170) · ultrarslanoglu/botbuilder-python@fddd368 · GitHub
[go: up one dir, main page]

Skip to content
< 8000 script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/sessions-1e75b15ae60a.js">

Commit fddd368

Browse files
authored
Add new Teams invoke types 'config/fetch' and 'config/submit' (microsoft#2170)
1 parent 0fba27b commit fddd368

File tree

8 files changed

+237
-0
lines changed

8 files changed

+237
-0
lines changed

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

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,22 @@ async def on_invoke_activity(self, turn_context: TurnContext) -> InvokeResponse:
186186
)
187187
)
188188

189+
if turn_context.activity.name == "config/fetch":
190+
return self._create_invoke_response(
191+
await self.on_teams_config_fetch(
192+
turn_context,
193+
turn_context.activity.value,
194+
)
195+
)
196+
197+
if turn_context.activity.name == "config/submit":
198+
return self._create_invoke_response(
199+
await self.on_teams_config_submit(
200+
turn_context,
201+
turn_context.activity.value,
202+
)
203+
)
204+
189205
return await super().on_invoke_activity(turn_context)
190206

191207
except _InvokeResponseException as invoke_exception:
@@ -515,6 +531,32 @@ async def on_teams_tab_submit( # pylint: disable=unused-argument
515531
"""
516532
raise _InvokeResponseException(status_code=HTTPStatus.NOT_IMPLEMENTED)
517533

534+
async def on_teams_config_fetch( # pylint: disable=unused-argument
535+
self, turn_context: TurnContext, config_data: any
536+
):
537+
"""
538+
Override this in a derived class to provide logic for when a config is fetched.
539+
540+
:param turn_context: A context object for this turn.
541+
:param config_data: The config fetch invoke request value payload.
542+
543+
:returns: A Config Response for the request.
544+
"""
545+
raise _InvokeResponseException(status_code=HTTPStatus.NOT_IMPLEMENTED)
546+
547+
async def on_teams_config_submit( # pylint: disable=unused-argument
548+
self, turn_context: TurnContext, config_data: any
549+
):
550+
"""
551+
Override this in a derived class to provide logic for when a config is submitted.
552+
553+
:param turn_context: A context object for this turn.
554+
:param config_data: The config fetch invoke request value payload.
555+
556+
:returns: A Config Response for the request.
557+
"""
558+
raise _InvokeResponseException(status_code=HTTPStatus.NOT_IMPLEMENTED)
559+
518560
async def on_conversation_update_activity(self, turn_context: TurnContext):
519561
"""
520562
Invoked when a conversation update activity is received from the channel.

libraries/botbuilder-core/tests/teams/test_teams_activity_handler.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,14 @@ async def on_teams_tab_submit(
315315
self.record.append("on_teams_tab_submit")
316316
return await super().on_teams_tab_submit(turn_context, tab_submit)
317317

318+
async def on_teams_config_fetch(self, turn_context: TurnContext, config_data: any):
319+
self.record.append("on_teams_config_fetch")
320+
return await super().on_teams_config_fetch(turn_context, config_data)
321+
322+
async def on_teams_config_submit(self, turn_context: TurnContext, config_data: any):
323+
self.record.append("on_teams_config_submit")
324+
return await super().on_teams_config_submit(turn_context, config_data)
325+
318326
async def on_event_activity(self, turn_context: TurnContext):
319327
self.record.append("on_event_activity")
320328
return await super().on_event_activity(turn_context)
@@ -1126,6 +1134,50 @@ async def test_on_teams_tab_submit(self):
11261134
assert bot.record[0] == "on_invoke_activity"
11271135
assert bot.record[1] == "on_teams_tab_submit"
11281136

1137+
async def test_on_teams_config_fetch(self):
1138+
# Arrange
1139+
activity = Activity(
1140+
type=ActivityTypes.invoke,
1141+
name="config/fetch",
1142+
value={
1143+
"data": {"key": "value", "type": "config/fetch"},
1144+
"context": {"theme": "default"},
1145+
},
1146+
)
1147+
1148+
turn_context = TurnContext(SimpleAdapter(), activity)
1149+
1150+
# Act
1151+
bot = TestingTeamsActivityHandler()
1152+
await bot.on_turn(turn_context)
1153+
1154+
# Assert
1155+
assert len(bot.record) == 2
1156+
assert bot.record[0] == "on_invoke_activity"
1157+
assert bot.record[1] == "on_teams_config_fetch"
1158+
1159+
async def test_on_teams_config_submit(self):
1160+
# Arrange
1161+
activity = Activity(
1162+
type=ActivityTypes.invoke,
1163+
name="config/submit",
1164+
value={
1165+
"data": {"key": "value", "type": "config/submit"},
1166+
"context": {"theme": "default"},
1167+
},
1168+
)
1169+
1170+
turn_context = TurnContext(SimpleAdapter(), activity)
1171+
1172+
# Act
1173+
bot = TestingTeamsActivityHandler()
1174+
await bot.on_turn(turn_context)
1175+
1176+
# Assert
1177+
assert len(bot.record) == 2
1178+
assert bot.record[0] == "on_invoke_activity"
1179+
assert bot.record[1] == "on_teams_config_submit"
1180+
11291181
async def test_on_end_of_conversation_activity(self):
11301182
activity = Activity(type=ActivityTypes.end_of_conversation)
11311183

libraries/botbuilder-schema/botbuilder/schema/teams/__init__.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,10 @@
8181
from ._models_py3 import TeamsMeetingMember
8282
from ._models_py3 import MeetingParticipantsEventDetails
8383
from ._models_py3 import ReadReceiptInfo
84+
from ._models_py3 import BotConfigAuth
85+
from ._models_py3 import ConfigAuthResponse
86+
from ._models_py3 import ConfigResponse
87+
from ._models_py3 import ConfigTaskResponse
8488

8589
__all__ = [
8690
"AppBasedLinkQuery",
@@ -163,4 +167,8 @@
163167
"TeamsMeetingMember",
164168
"MeetingParticipantsEventDetails",
165169
"ReadReceiptInfo",
170+
"BotConfigAuth",
171+
"ConfigAuthResponse",
172+
"ConfigResponse",
173+
"ConfigTaskResponse",
166174
]

libraries/botbuilder-schema/botbuilder/schema/teams/_models_py3.py

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2619,3 +2619,83 @@ def is_message_read_instance(self, compare_message_id):
26192619
return ReadReceiptInfo.is_message_read(
26202620
compare_message_id, self.last_read_message_id
26212621
)
2622+
2623+
2624+
class BotConfigAuth(Model):
2625+
"""Specifies bot config auth, including type and suggestedActions.
2626+
2627+
:param type: The type of bot config auth.
2628+
:type type: str
2629+
:param suggested_actions: The suggested actions of bot config auth.
2630+
:type suggested_actions: ~botframework.connector.models.SuggestedActions
2631+
"""
2632+
2633+
_attribute_map = {
2634+
"type": {"key": "type", "type": "str"},
2635+
"suggested_actions": {"key": "suggestedActions", "type": "SuggestedActions"},
2636+
}
2637+
2638+
def __init__(self, *, type: str = "auth", suggested_actions=None, **kwargs) -> None:
2639+
super(BotConfigAuth, self).__init__(**kwargs)
2640+
self.type = type
2641+
self.suggested_actions = suggested_actions
2642+
2643+
2644+
class ConfigResponseBase(Model):
2645+
"""Specifies Invoke response base, including response type.
2646+
2647+
:param response_type: Response type for invoke request
2648+
:type response_type: str
2649+
"""
2650+
2651+
_attribute_map = {
2652+
"response_type": {"key": "responseType", "type": "str"},
2653+
}
2654+
2655+
def __init__(self, *, response_type: str = None, **kwargs) -> None:
2656+
super(ConfigResponseBase, self).__init__(**kwargs)
2657+
self.response_type = response_type
2658+
2659+
2660+
class ConfigResponse(ConfigResponseBase):
2661+
"""Envelope for Config Response Payload.
2662+
2663+
:param config: The response to the config message. Possible values: 'auth', 'task'
2664+
:type config: T
2665+
:param cache_info: Response cache info
2666+
:type cache_info: ~botframework.connector.teams.models.CacheInfo
2667+
"""
2668+
2669+
_attribute_map = {
2670+
"config": {"key": "config", "type": "object"},
2671+
"cache_info": {"key": "cacheInfo", "type": "CacheInfo"},
2672+
}
2673+
2674+
def __init__(self, *, config=None, cache_info=None, **kwargs) -> None:
2675+
super(ConfigResponse, self).__init__(response_type="config", **kwargs)
2676+
self.config = config
2677+
self.cache_info = cache_info
2678+
2679+
2680+
class ConfigTaskResponse(ConfigResponse):
2681+
"""Envelope for Config Task Response.
2682+
2683+
This class uses TaskModuleResponseBase as the type for the config parameter.
2684+
"""
2685+
2686+
def __init__(self, *, config=None, **kwargs) -> None:
2687+
super(ConfigTaskResponse, self).__init__(
2688+
config=config or TaskModuleResponseBase(), **kwargs
2689+
)
2690+
2691+
2692+
class ConfigAuthResponse(ConfigResponse):
2693+
"""Envelope for Config Auth Response.
2694+
2695+
This class uses BotConfigAuth as the type for the config parameter.
2696+
"""
2697+
2698+
def __init__(self, *, config=None, **kwargs) -> None:
2699+
super(ConfigAuthResponse, self).__init__(
2700+
config=config or BotConfigAuth(), **kwargs
2701+
)
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Copyright (c) Microsoft Corporation. All rights reserved.
2+
# Licensed under the MIT License.
3+
4+
import aiounittest
5+
from botbuilder.schema.teams import BotConfigAuth
6+
7+
8+
class TestBotConfigAuth(aiounittest.AsyncTestCase):
9+
def test_bot_config_auth_inits_with_no_args(self):
10+
bot_config_auth_response = BotConfigAuth()
11+
12+
self.assertIsNotNone(bot_config_auth_response)
13+
self.assertIsInstance(bot_config_auth_response, BotConfigAuth)
14+
self.assertEqual("auth", bot_config_auth_response.type)
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Copyright (c) Microsoft Corporation. All rights reserved.
2+
# Licensed under the MIT License.
3+
4+
import aiounittest
5+
from botbuilder.schema.teams import ConfigAuthResponse
6+
7+
8+
class TestConfigAuthResponse(aiounittest.AsyncTestCase):
9+
def test_config_auth_response_init_with_no_args(self):
10+
config_auth_response = ConfigAuthResponse()
11+
12+
self.assertIsNotNone(config_auth_response)
13+
self.assertIsInstance(config_auth_response, ConfigAuthResponse)
14+
self.assertEqual("config", config_auth_response.response_type)
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Copyright (c) Microsoft Corporation. All rights reserved.
2+
# Licensed under the MIT License.
3+
4+
import aiounittest
5+
from botbuilder.schema.teams import ConfigResponse
6+
7+
8+
class TestConfigResponse(aiounittest.AsyncTestCase):
9+
def test_config_response_inits_with_no_args(self):
10+
config_response = ConfigResponse()
11+
12+
self.assertIsNotNone(config_response)
13+
self.assertIsInstance(config_response, ConfigResponse)
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Copyright (c) Microsoft Corporation. All rights reserved.
2+
# Licensed under the MIT License.
3+
4+
import aiounittest
5+
from botbuilder.schema.teams import ConfigTaskResponse
6+
7+
8+
class TestConfigTaskResponse(aiounittest.AsyncTestCase):
9+
def test_config_task_response_init_with_no_args(self):
10+
config_task_response = ConfigTaskResponse()
11+
12+
self.assertIsNotNone(config_task_response)
13+
self.assertIsInstance(config_task_response, ConfigTaskResponse)
14+
self.assertEqual("config", config_task_response.response_type)

0 commit comments

Comments
 (0)
0