8000 Merge pull request #801 from microsoft/trboehre/continueconversation · guptarohan41/botbuilder-python@5ed1497 · GitHub
[go: up one dir, main page]

Skip to content

Commit 5ed1497

Browse files
authored
Merge pull request microsoft#801 from microsoft/trboehre/continueconversation
Refactor BFAdapter Auth, Add support for proactively messaging
2 parents acfe129 + a16ed3b commit 5ed1497

File tree

11 files changed

+1072
-632
lines changed

11 files changed

+1072
-632
lines changed

libraries/botbuilder-adapters-slack/botbuilder/adapters/slack/slack_adapter.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,9 @@ async def continue_conversation(
130130
self,
131131
reference: ConversationReference,
132132
callback: Callable,
133-
bot_id: str = None, # pylint: disable=unused-argument
134-
claims_identity: ClaimsIdentity = None, # pylint: disable=unused-argument
133+
bot_id: str = None,
134+
claims_identity: ClaimsIdentity = None,
135+
audience: str = None,
135136
):
136137
"""
137138
Sends a proactive message to a conversation. Call this method to proactively send a message to a conversation.

libraries/botbuilder-core/botbuilder/core/adapters/test_adapter.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,8 @@ async def continue_conversation(
164164
reference: ConversationReference,
165165
callback: Callable,
166166
bot_id: str = None,
167-
claims_identity: ClaimsIdentity = None, # pylint: disable=unused-argument
167+
claims_identity: ClaimsIdentity = None,
168+
audience: str = None,
168169
):
169170
"""
170171
The `TestAdapter` just calls parent implementation.
@@ -175,7 +176,7 @@ async def continue_conversation(
175176
:return:
176177< E864 /code>
"""
177178
await super().continue_conversation(
178-
reference, callback, bot_id, claims_identity
179+
reference, callback, bot_id, claims_identity, audience
179180
)
180181

181182
async def receive_activity(self, activity):
Lines changed: 120 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -1,113 +1,120 @@
1-
# Copyright (c) Microsoft Corporation. All rights reserved.
2-
# Licensed under the MIT License.
3-
4-
from abc import ABC, abstractmethod
5-
from typing import List, Callable, Awaitable
6-
from botbuilder.schema import Activity, ConversationReference, ResourceResponse
7-
from botframework.connector.auth import ClaimsIdentity
8-
9-
from . import conversation_reference_extension
10-
from .bot_assert import BotAssert
11-
from .turn_context import TurnContext
12-
from .middleware_set import MiddlewareSet
13-
14-
15-
class BotAdapter(ABC):
16-
def __init__(
17-
self, on_turn_error: Callable[[TurnContext, Exception], Awaitable] = None
18-
):
19-
self._middleware = MiddlewareSet()
20-
self.on_turn_error = on_turn_error
21-
22-
@abstractmethod
23-
async def send_activities(
24-
self, context: TurnContext, activities: List[Activity]
25-
) -> List[ResourceResponse]:
26-
"""
27-
Sends a set of activities to the user. An array of responses from the server will be returned.
28-
:param context:
29-
:param activities:
30-
:return:
31-
"""
32-
raise NotImplementedError()
33-
34-
@abstractmethod
35-
async def update_activity(self, context: TurnContext, activity: Activity):
36-
"""
37-
Replaces an existing activity.
38-
:param context:
39-
:param activity:
40-
:return:
41-
"""
42-
raise NotImplementedError()
43-
44-
@abstractmethod
45-
async def delete_activity(
46-
self, context: TurnContext, reference: ConversationReference
47-
):
48-
"""
49-
Deletes an existing activity.
50-
:param context:
51-
:param reference:
52-
:return:
53-
"""
54-
raise NotImplementedError()
55-
56-
def use(self, middleware):
57-
"""
58-
Registers a middleware handler with the adapter.
59-
:param middleware:
60-
:return:
61-
"""
62-
self._middleware.use(middleware)
63-
return self
64-
65-
async def continue_conversation(
66-
self,
67-
reference: ConversationReference,
68-
callback: Callable,
69-
bot_id: str = None, # pylint: disable=unused-argument
70-
claims_identity: ClaimsIdentity = None, # pylint: disable=unused-argument
71-
):
72-
"""
73-
Sends a proactive message to a conversation. Call this method to proactively send a message to a conversation.
74-
Most _channels require a user to initiate a conversation with a bot before the bot can send activities
75-
to the user.
76-
:param bot_id: The application ID of the bot. This parameter is ignored in
77-
single tenant the Adpters (Console, Test, etc) but is critical to the BotFrameworkAdapter
78-
which is multi-tenant aware. </param>
79-
:param reference: A reference to the conversation to continue.</param>
80-
:param callback: The method to call for the resulting bot turn.</param>
81-
:param claims_identity:
82-
"""
83-
context = TurnContext(
84-
self, conversation_reference_extension.get_continuation_activity(reference)
85-
)
86-
return await self.run_pipeline(context, callback)
87-
88-
async def run_pipeline(
89-
self, context: TurnContext, callback: Callable[[TurnContext], Awaitable] = None
90-
):
91-
"""
92-
Called by the parent class to run the adapters middleware set and calls the passed in `callback()` handler at
93-
the end of the chain.
94-
:param context:
95-
:param callback:
96-
:return:
97-
"""
98-
BotAssert.context_not_none(context)
99-
100-
if context.activity is not None:
101-
try:
102-
return await self._middleware.receive_activity_with_status(
103-
context, callback
104-
)
105-
except Exception as error:
106-
if self.on_turn_error is not None:
107-
await self.on_turn_error(context, error)
108-
else:
109-
raise error
110-
else:
111-
# callback to caller on proactive case
112-
if callback is not None:
113-
await callback(context)
1+
# Copyright (c) Microsoft Corporation. All rights reserved.
2+
# Licensed under the MIT License.
3+
4+
from abc import ABC, abstractmethod
5+
from typing import List, Callable, Awaitable
6+
from botbuilder.schema import Activity, ConversationReference, ResourceResponse
7+
from botframework.connector.auth import ClaimsIdentity
8+
9+
from . import conversation_reference_extension
10+
from .bot_assert import BotAssert
11+
from .turn_context import TurnContext
12+
from .middleware_set import MiddlewareSet
13+
14+
15+
class BotAdapter(ABC):
16+
BOT_IDENTITY_KEY = "BotIdentity"
17+
BOT_OAUTH_SCOPE_KEY = "OAuthScope"
18+
BOT_CONNECTOR_CLIENT_KEY = "ConnectorClient"
19+
BOT_CALLBACK_HANDLER_KEY = "BotCallbackHandler"
20+
21+
def __init__(
22+
self, on_turn_error: Callable[[TurnContext, Exception], Awaitable] = None
23+
):
24+
self._middleware = MiddlewareSet()
25+
self.on_turn_error = on_turn_error
26+
27+
@abstractmethod
28+
async def send_activities(
29+
self, context: TurnContext, activities: List[Activity]
30+
) -> List[ResourceResponse]:
31+
"""
32+
Sends a set of activities to the user. An array of responses from the server will be returned.
33+
:param context:
34+
:param activities:
35+
:return:
36+
"""
37+
raise NotImplementedError()
38+
39+
@abstractmethod
40+
async def update_activity(self, context: TurnContext, activity: Activity):
41+
"""
42+
Replaces an existing activity.
43+
:param context:
44+
:param activity:
45+
:return:
46+
"""
47+
raise NotImplementedError()
48+
49+
@abstractmethod
50+
async def delete_activity(
51+
self, context: TurnContext, reference: ConversationReference
52+
):
53+
"""
54+
Deletes an existing activity.
55+
:param context:
56+
:param reference:
57+
:return:
58+
"""
59+
raise NotImplementedError()
60+
61+
def use(self, middleware):
62+
"""
63+
Registers a middleware handler with the adapter.
64+
:param middleware:
65+
:return:
66+
"""
67+
self._middleware.use(middleware)
68+
return self
69+
70+
async def continue_conversation(
71+
self,
72+
reference: ConversationReference,
73+
callback: Callable,
74+
bot_id: str = None, # pylint: disable=unused-argument
75+
claims_identity: ClaimsIdentity = None, # pylint: disable=unused-argument
76+
audience: str = None, # pylint: disable=unused-argument
77+
):
78+
"""
79+
Sends a proactive message to a conversation. Call this method to proactively send a message to a conversation.
80+
Most _channels require a user to initiate a conversation with a bot before the bot can send activities
81+
to the user.
82+
:param bot_id: The application ID of the bot. This parameter is ignored in
83+
single tenant the Adpters (Console, Test, etc) but is critical to the BotFrameworkAdapter
84+
which is multi-tenant aware. </param>
85+
:param reference: A reference to the conversation to continue.</param>
86+
:param callback: The method to call for the resulting bot turn.</param>
87+
:param claims_identity:
88+
:param audience:
89+
"""
90+
context = TurnContext(
91+
self, conversation_reference_extension.get_continuation_activity(reference)
92+
)
93+
return await self.run_pipeline(context, callback)
94+
95+
async def run_pipeline(
96+
self, context: TurnContext, callback: Callable[[TurnContext], Awaitable] = None
97+
):
98+
"""
99+
Called by the parent class to run the adapters middleware set and calls the passed in `callback()` handler at
100+
the end of the chain.
101+
:param context:
102+
:param callback:
103+
:return:
104+
"""
105+
BotAssert.context_not_none(context)
106+
107+
if context.activity is not None:
108+
try:
109+
return await self._middleware.receive_activity_with_status(
110+
context, callback
111+
)
112+
except Exception as error:
113+
if self.on_turn_error is not None:
114+
await self.on_turn_error(context, error)
115+
else:
116+
raise error
117+
else:
118+
# callback to caller on proactive case
119+
if callback is not None:
120+
await callback(context)

0 commit comments

Comments
 (0)
0