Skip to content

Adaptive Card Tabs #1486

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Feb 17, 2021
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
O365ConnectorCardActionQuery,
TaskModuleRequest,
TaskModuleResponse,
TabRequest,
TabSubmit,
)
from botframework.connector import Channels
from ..serializer_helper import deserializer_helper
Expand Down Expand Up @@ -163,6 +165,22 @@ async def on_invoke_activity(self, turn_context: TurnContext) -> InvokeResponse:
)
)

if turn_context.activity.name == "tab/fetch":
return self._create_invoke_response(
await self.on_teams_tab_fetch(
turn_context,
deserializer_helper(TabRequest, turn_context.activity.value),
)
)

if turn_context.activity.name == "tab/submit":
return self._create_invoke_response(
await self.on_teams_tab_submit(
turn_context,
deserializer_helper(TabSubmit, turn_context.activity.value),
)
)

return await super().on_invoke_activity(turn_context)

except _InvokeResponseException as invoke_exception:
Expand Down Expand Up @@ -466,6 +484,32 @@ async def on_teams_task_module_submit( # pylint: disable=unused-argument
"""
raise _InvokeResponseException(status_code=HTTPStatus.NOT_IMPLEMENTED)

async def on_teams_tab_fetch( # pylint: disable=unused-argument
self, turn_context: TurnContext, tab_request: TabRequest
):
"""
Override this in a derived class to provide logic for when a tab is fetched.

:param turn_context: A context object for this turn.
:param tab_request: The tab invoke request value payload.

:returns: A Tab Response for the request.
"""
raise _InvokeResponseException(status_code=HTTPStatus.NOT_IMPLEMENTED)

async def on_teams_tab_submit( # pylint: disable=unused-argument
self, turn_context: TurnContext, tab_submit: TabSubmit
):
"""
Override this in a derived class to provide logic for when a tab is submitted.

:param turn_context: A context object for this turn.
:param tab_submit: The tab submit invoke request value payload.

:returns: A Tab Response for the request.
"""
raise _InvokeResponseException(status_code=HTTPStatus.NOT_IMPLEMENTED)

async def on_conversation_update_activity(self, turn_context: TurnContext):
"""
Invoked when a conversation update activity is received from the channel.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@
TaskModuleRequestContext,
TeamInfo,
TeamsChannelAccount,
TabRequest,
TabSubmit,
TabContext,
)
from botframework.connector import Channels
from simple_adapter import SimpleAdapter
Expand Down Expand Up @@ -294,6 +297,18 @@ async def on_teams_task_module_submit( # pylint: disable=unused-argument
turn_context, task_module_request
)

async def on_teams_tab_fetch(
self, turn_context: TurnContext, tab_request: TabRequest
):
self.record.append("on_teams_tab_fetch")
return await super().on_teams_tab_fetch(turn_context, tab_request)

async def on_teams_tab_submit(
self, turn_context: TurnContext, tab_submit: TabSubmit
):
self.record.append("on_teams_tab_submit")
return await super().on_teams_tab_submit(turn_context, tab_submit)


class NotImplementedAdapter(BotAdapter):
async def delete_activity(
Expand Down Expand Up @@ -988,6 +1003,44 @@ async def test_on_teams_task_module_submit(self):
assert bot.record[0] == "on_invoke_activity"
assert bot.record[1] == "on_teams_task_module_submit"

async def test_on_teams_tab_fetch(self):
# Arrange
activity = Activity(
type=ActivityTypes.invoke,
name="tab/fetch",
value={"data": {"key": "value"}, "context": TabContext().serialize(),},
)

turn_context = TurnContext(SimpleAdapter(), activity)

# Act
bot = TestingTeamsActivityHandler()
await bot.on_turn(turn_context)

# Assert
assert len(bot.record) == 2
assert bot.record[0] == "on_invoke_activity"
assert bot.record[1] == "on_teams_tab_fetch"

async def test_on_teams_tab_submit(self):
# Arrange
activity = Activity(
type=ActivityTypes.invoke,
name="tab/submit",
value={"data": {"key": "value"}, "context": TabContext().serialize(),},
)

turn_context = TurnContext(SimpleAdapter(), activity)

# Act
bot = TestingTeamsActivityHandler()
await bot.on_turn(turn_context)

# Assert
assert len(bot.record) == 2
assert bot.record[0] == "on_invoke_activity"
assert bot.record[1] == "on_teams_tab_submit"

async def test_on_end_of_conversation_activity(self):
activity = Activity(type=ActivityTypes.end_of_conversation)

Expand Down
18 changes: 18 additions & 0 deletions libraries/botbuilder-schema/botbuilder/schema/teams/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,15 @@
from ._models_py3 import TeamsMeetingParticipant
from ._models_py3 import MeetingParticipantInfo
from ._models_py3 import CacheInfo
from ._models_py3 import TabContext
from ._models_py3 import TabRequest
from ._models_py3 import TabResponseCard
from ._models_py3 import TabResponseCards
from ._models_py3 import TabResponsePayload
from ._models_py3 import TabSubmit
from ._models_py3 import TabSubmitData
from ._models_py3 import TabSuggestedActions
from ._models_py3 import TaskModuleCardResponse

__all__ = [
"AppBasedLinkQuery",
Expand Down Expand Up @@ -125,4 +134,13 @@
"TeamsMeetingParticipant",
"MeetingParticipantInfo",
"CacheInfo",
"TabContext",
"TabRequest",
"TabResponseCard",
"TabResponseCards",
"TabResponsePayload",
"TabSubmit",
"TabSubmitData",
"TabSuggestedActions",
"TaskModuleCardResponse",
]
Loading