10000 Port: Add support for new Teams invoke types 'config/fetch' and 'config/submit' by gandiddi · Pull Request #2170 · microsoft/botbuilder-python · GitHub
[go: up one dir, main page]

Skip to content

Port: Add support for new Teams invoke types 'config/fetch' and 'config/submit' #2170

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 1 commit into from
Sep 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8000
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,22 @@ async def on_invoke_activity(self, turn_context: TurnContext) -> InvokeResponse:
)
)

if turn_context.activity.name == "config/fetch":
return self._create_invoke_response(
await self.on_teams_config_fetch(
turn_context,
turn_context.activity.value,
)
)

if turn_context.activity.name == "config/submit":
return self._create_invoke_response(
await self.on_teams_config_submit(
turn_context,
turn_context.activity.value,
)
)

return await super().on_invoke_activity(turn_context)

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

async def on_teams_config_fetch( # pylint: disable=unused-argument
self, turn_context: TurnContext, config_data: any
):
"""
Override this in a derived class to provide logic for when a config is fetched.

:param turn_context: A context object for this turn.
:param config_data: The config fetch invoke request value payload.

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

async def on_teams_config_submit( # pylint: disable=unused-argument
self, turn_context: TurnContext, config_data: any
):
"""
Override this in a derived class to provide logic for when a config is submitted.

:param turn_context: A context object for this turn.
:param config_data: The config fetch invoke request value payload.

:returns: A Config Response for the request.
"""
10000 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 @@ -315,6 +315,14 @@ async def on_teams_tab_submit(
self.record.append("on_teams_tab_submit")
return await super().on_teams_tab_submit(turn_context, tab_submit)

async def on_teams_config_fetch(self, turn_context: TurnContext, config_data: any):
self.record.append("on_teams_config_fetch")
return await super().on_teams_config_fetch(turn_context, config_data)

async def on_teams_config_submit(self, turn_context: TurnContext, config_data: any):
self.record.append("on_teams_config_submit")
return await super().on_teams_config_submit(turn_context, config_data)

async def on_event_activity(self, turn_context: TurnContext):
self.record.append("on_event_activity")
return await super().on_event_activity(turn_context)
Expand Down Expand Up @@ -1126,6 +1134,50 @@ async def test_on_teams_tab_submit(self):
assert bot.record[0] == "on_invoke_activity"
assert bot.record[1] == "on_teams_tab_submit"

async def test_on_teams_config_fetch(self):
# Arrange
activity = Activity(
type=ActivityTypes.invoke,
name="config/fetch",
value={
"data": {"key": "value", "type": "config/fetch"},
"context": {"theme": "default"},
},
)

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_config_fetch"

async def test_on_teams_config_submit(self):
# Arrange
activity = Activity(
type=ActivityTypes.invoke,
name="config/submit",
value={
"data": {"key": "value", "type": "config/submit"},
"context": {"theme": "default"},
},
)

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_config_submit"

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@
from ._models_py3 import TeamsMeetingMember
from ._models_py3 import MeetingParticipantsEventDetails
from ._models_py3 import ReadReceiptInfo
from ._models_py3 import BotConfigAuth
from ._models_py3 import ConfigAuthResponse
from ._models_py3 import ConfigResponse
from ._models_py3 import ConfigTaskResponse

__all__ = [
"AppBasedLinkQuery",
Expand Down Expand Up @@ -163,4 +167,8 @@
"TeamsMeetingMember",
"MeetingParticipantsEventDetails",
"ReadReceiptInfo",
"BotConfigAuth",
"ConfigAuthResponse",
"ConfigResponse",
"ConfigTaskResponse",
]
80 changes: 80 additions & 0 deletions libraries/botbuilder-schema/botbuilder/schema/teams/_models_py3.py
Original file line number Diff line number Diff line change
Expand Up @@ -2619,3 +2619,83 @@ def is_message_read_instance(self, compare_message_id):
return ReadReceiptInfo.is_message_read(
compare_message_id, self.last_read_message_id
)


class BotConfigAuth(Model):
"""Specifies bot config auth, including type and suggestedActions.

:param type: The type of bot config auth.
:type type: str
:param suggested_actions: The suggested actions of bot config auth.
:type suggested_actions: ~botframework.connector.models.SuggestedActions
"""

_attribute_map = {
"type": {"key": "type", "type": "str"},
"suggested_actions": {"key": "suggestedActions", "type": "SuggestedActions"},
}

def __init__(self, *, type: str = "auth", suggested_actions=None, **kwargs) -> None:
super(BotConfigAuth, self).__init__(**kwargs)
self.type = type
self.suggested_actions = suggested_actions


class ConfigResponseBase(Model):
"""Specifies Invoke response base, including response type.

:param response_type: Response type for invoke request
:type response_type: str
"""

_attribute_map = {
"response_type": {"key": "responseType", "type": "str"},
}

def __init__(self, *, response_type: str = None, **kwargs) -> None:
super(ConfigResponseBase, self).__init__(**kwargs)
self.response_type = response_type


class ConfigResponse(ConfigResponseBase):
"""Envelope for Config Response Payload.

:param config: The response to the config message. Possible values: 'auth', 'task'
:type config: T
:param cache_info: Response cache info
:type cache_info: ~botframework.connector.teams.models.CacheInfo
"""

_attribute_map = {
"config": {"key": "config", "type": "object"},
"cache_info": {"key": "cacheInfo", "type": "CacheInfo"},
}

def __init__(self, *, config=None, cache_info=None, **kwargs) -> None:
super(ConfigResponse, self).__init__(response_type="config", **kwargs)
self.config = config
self.cache_info = cache_info


class ConfigTaskResponse(ConfigResponse):
"""Envelope for Config Task Response.

This class uses TaskModuleResponseBase as the type for the config parameter.
"""

def __init__(self, *, config=None, **kwargs) -> None:
super(ConfigTaskResponse, self).__init__(
config=config or TaskModuleResponseBase(), **kwargs
)


class ConfigAuthResponse(ConfigResponse):
"""Envelope for Config Auth Response.

This class uses BotConfigAuth as the type for the config parameter.
"""

def __init__(self, *, config=None, **kwargs) -> None:
super(ConfigAuthResponse, self).__init__(
config=config or BotConfigAuth(), **kwargs
)
14 changes: 14 additions & 0 deletions 9E7A libraries/botbuilder-schema/tests/teams/test_bot_config_auth.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

import aiounittest
from botbuilder.schema.teams import BotConfigAuth


class TestBotConfigAuth(aiounittest.AsyncTestCase):
def test_bot_config_auth_inits_with_no_args(self):
bot_config_auth_response = BotConfigAuth()

self.assertIsNotNone(bot_config_auth_response)
self.assertIsInstance(bot_config_auth_response, BotConfigAuth)
self.assertEqual("auth", bot_config_auth_response.type)
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

import aiounittest
from botbuilder.schema.teams import ConfigAuthResponse


class TestConfigAuthResponse(aiounittest.AsyncTestCase):
def test_config_auth_response_init_with_no_args(self):
config_auth_response = ConfigAuthResponse()

self.assertIsNotNone(config_auth_response)
self.assertIsInstance(config_auth_response, ConfigAuthResponse)
self.assertEqual("config", config_auth_response.response_type)
13 changes: 13 additions & 0 deletions libraries/botbuilder-schema/tests/teams/test_config_response.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

import aiounittest
from botbuilder.schema.teams import ConfigResponse


class TestConfigResponse(aiounittest.AsyncTestCase):
def test_config_response_inits_with_no_args(self):
config_response = ConfigResponse()

self.assertIsNotNone(config_response)
self.assertIsInstance(config_response, ConfigResponse)
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

import aiounittest
from botbuilder.schema.teams import ConfigTaskResponse


class TestConfigTaskResponse(aiounittest.AsyncTestCase):
def test_config_task_response_init_with_no_args(self):
config_task_response = ConfigTaskResponse()

self.assertIsNotNone(config_task_response)
self.assertIsInstance(config_task_response, ConfigTaskResponse)
self.assertEqual("config", config_task_response.response_type)
Loading
0