33
44import asyncio
55from typing import List , Callable
6- from botbuilder .schema import Activity , ChannelAccount , ConversationReference , ConversationsResult
6+ from botbuilder .schema import (Activity , ChannelAccount ,
7+ ConversationAccount ,
8+ ConversationParameters , ConversationReference ,
9+ ConversationsResult , ConversationResourceResponse )
710from botframework .connector import ConnectorClient
811from botframework .connector .auth import (MicrosoftAppCredentials ,
912 JwtTokenValidation , SimpleCredentialProvider )
@@ -29,12 +32,56 @@ def __init__(self, settings: BotFrameworkAdapterSettings):
2932 self ._credentials = MicrosoftAppCredentials (self .settings .app_id , self .settings .app_password )
3033 self ._credential_provider = SimpleCredentialProvider (self .settings .app_id , self .settings .app_password )
3134
32- async def process_request (self , req , auth_header : str , logic : Callable ):
33- request = await self .parse_request (req )
35+ async def continue_conversation (self , reference : ConversationReference , logic ):
36+ """
37+ Continues a conversation with a user. This is often referred to as the bots "Proactive Messaging"
38+ flow as its lets the bot proactively send messages to a conversation or user that its already
39+ communicated with. Scenarios like sending notifications or coupons to a user are enabled by this
40+ method.
41+ :param reference:
42+ :param logic:
43+ :return:
44+ """
45+ request = BotContext .apply_conversation_reference (Activity (), reference , is_incoming = True )
46+ context = self .create_context (request )
47+ return await self .run_middleware (context , logic )
48+
49+ async def create_conversation (self , reference : ConversationReference , logic ):
50+ try :
51+ if reference .service_url is None :
52+ raise TypeError ('BotFrameworkAdapter.create_conversation(): reference.service_url cannot be None.' )
53+
54+ # Create conversation
55+ parameters = ConversationParameters (bot = reference .bot )
56+ client = self .create_connector_client (reference .service_url )
57+
58+ resource_response = await client .conversations .create_conversation_async (parameters )
59+ request = BotContext .apply_conversation_reference (Activity (), reference , is_incoming = True )
60+ request .conversation = ConversationAccount (id = resource_response .id )
61+ if resource_response .service_url :
62+ request .service_url = resource_response .service_url
63+
64+ context = self .create_context (request )
65+ return await self .run_middleware (context , logic )
66+
67+ except Exception as e :
68+ raise e
69+
70+ async def process_activity (self , req , auth_header : str , logic : Callable ):
71+ """
72+ Processes an activity received by the bots web server. This includes any messages sent from a
73+ user and is the method that drives what's often referred to as the bots "Reactive Messaging"
74+ flow.
75+ :param req:
76+ :param auth_header:
77+ :param logic:
78+ :return:
79+ """
80+ activity = await self .parse_request (req )
3481 auth_header = auth_header or ''
3582
36- await self .authenticate_request (request , auth_header )
37- context = self .create_context (request )
83+ await self .authenticate_request (activity , auth_header )
84+ context = self .create_context (activity )
3885
3986 return await self .run_middleware (context , logic )
4087
@@ -84,22 +131,34 @@ async def validate_activity(activity: Activity):
84131 return req
85132
86133 async def update_activity (self , context : BotContext , activity : Activity ):
134+ """
135+ Replaces an activity that was previously sent to a channel. It should be noted that not all
136+ channels support this feature.
137+ :param context:
138+ :param activity:
139+ :return:
140+ """
87141 try :
88- connector_client = ConnectorClient (self ._credentials , activity .service_url )
89- connector_client .config .add_user_agent (USER_AGENT )
90- return await connector_client .conversations .update_activity_async (
142+ client = self .create_connector_client (activity .service_url )
143+ return await client .conversations .update_activity_async (
91144 activity .conversation .id ,
92145 activity .conversation .activity_id ,
93146 activity )
94147 except Exception as e :
95148 raise e
96149
97150 async def delete_activity (self , context : BotContext , conversation_reference : ConversationReference ):
151+ """
152+ Deletes an activity that was previously sent to a channel. It should be noted that not all
153+ channels support this feature.
154+ :param context:
155+ :param conversation_reference:
156+ :return:
157+ """
98158 try :
99- connector_client = ConnectorClient (self ._credentials , conversation_reference .service_url )
100- connector_client .config .add_user_agent (USER_AGENT )
101- await connector_client .conversations .delete_activity_async (conversation_reference .conversation .id ,
102- conversation_reference .activity_id )
159+ client = self .create_connector_client (conversation_reference .service_url )
160+ await client .conversations .delete_activity_async (conversation_reference .conversation .id ,
161+ conversation_reference .activity_id )
103162 except Exception as e :
104163 raise e
105164
@@ -116,9 +175,8 @@ async def send_activity(self, context: BotContext, activities: List[Activity]):
116175 else :
117176 await asyncio .sleep (delay_in_ms )
118177 else :
119- connector_client = ConnectorClient (self ._credentials , activity .service_url )
120- connector_client .config .add_user_agent (USER_AGENT )
121- await connector_client .conversations .send_to_conversation_async (activity .conversation .id , activity )
178+ client = self .create_connector_client (activity .service_url )
179+ await client .conversations .send_to_conversation_async (activity .conversation .id , activity )
122180 except Exception as e :
123181 raise e
124182
@@ -137,8 +195,7 @@ async def delete_conversation_member(self, context: BotContext, member_id: str)
137195 'conversation.id' )
138196 service_url = context .request .service_url
139197 conversation_id = context .request .conversation .id
140- client = ConnectorClient (self ._credentials , service_url )
141- client .config .add_user_agent (USER_AGENT )
198+ client = self .create_connector_client (service_url )
142199 return await client .conversations .delete_conversation_member_async (conversation_id , member_id )
143200 except AttributeError as attr_e :
144201 raise attr_e
@@ -164,8 +221,7 @@ async def get_activity_members(self, context: BotContext, activity_id: str):
164221 'context.activity.id' )
165222 service_url = context .request .service_url
166223 conversation_id = context .request .conversation .id
167- client = ConnectorClient (self ._credentials , service_url )
168- client .config .add_user_agent (USER_AGENT )
224+ client = self .create_connector_client (service_url )
169225 return await client .conversations .get_activity_members_async (conversation_id , activity_id )
170226 except Exception as e :
171227 raise e
@@ -184,8 +240,7 @@ async def get_conversation_members(self, context: BotContext):
184240 'conversation.id' )
185241 service_url = context .request .service_url
186242 conversation_id = context .request .conversation .id
187- client = ConnectorClient (self ._credentials , service_url )
188- client .config .add_user_agent (USER_AGENT )
243+ client = self .create_connector_client (service_url )
189244 return await client .conversations .get_conversation_members_async (conversation_id )
190245 except Exception as e :
191246 raise e
@@ -199,6 +254,10 @@ async def get_conversations(self, service_url: str, continuation_token: str=None
199254 :param continuation_token:
200255 :return:
201256 """
202- client = ConnectorClient (self ._credentials , service_url )
203- client .config .add_user_agent (USER_AGENT )
257+ client = self .create_connector_client (service_url )
204258 return await client .conversations .get_conversations_async (continuation_token )
259+
260+ def create_connector_client (self , service_url : str ) -> ConnectorClient :
261+ client = ConnectorClient (self ._credentials , base_url = service_url )
262+ client .config .add_user_agent (USER_AGENT )
263+ return client
0 commit comments