async def continue_conversation( self, reference: ConversationReference, callback: Callable, bot_id: str = None, # pylint: disable=unused-argument claims_identity: ClaimsIdentity = None, audience: str = None, # pylint: disable=unused-argument ): """ Send a proactive message to a conversation. .. remarks:: Most channels require a user to initiate a conversation with a bot before the bot can send activities to the user. :param reference: A reference to the conversation to continue. :type reference: :class:`botbuilder.schema.ConversationReference` :param callback: The method to call for the resulting bot turn. :type callback: :class:`typing.Callable` :param bot_id: Unused for this override. :type bot_id: str :param claims_identity: A ClaimsIdentity for the conversation. :type claims_identity: :class:`botframework.connector.auth.ClaimsIdentity` :param audience: Unused for this override. :type audience: str """ if not reference: raise Exception("ConversationReference is required") if not callback: raise Exception("callback is required") if claims_identity: request = conversation_reference_extension.get_continuation_activity( reference) context = TurnContext(self, request) context.turn_state[BotAdapter.BOT_IDENTITY_KEY] = claims_identity context.turn_state[BotAdapter.BOT_CALLBACK_HANDLER_KEY] = callback else: request = TurnContext.apply_conversation_reference( conversation_reference_extension.get_continuation_activity( reference), reference, ) context = TurnContext(self, request) return await self.run_pipeline(context, callback)
async def continue_conversation( self, reference: ConversationReference, callback: Callable, bot_id: str = None, claims_identity: ClaimsIdentity = None, audience: str = None, ): """ Sends a proactive message to a conversation. Call this method to proactively send a message to a conversation. Most _channels require a user to initiate a conversation with a bot before the bot can send activities to the user. :param bot_id: The application ID of the bot. This parameter is ignored in single tenant the Adpters (Console, Test, etc) but is critical to the BotFrameworkAdapter which is multi-tenant aware. </param> :param reference: A reference to the conversation to continue.</param> :param callback: The method to call for the resulting bot turn.</param> :param claims_identity: """ if not reference: raise Exception("ConversationReference is required") if not callback: raise Exception("callback is required") request = TurnContext.apply_conversation_reference( conversation_reference_extension.get_continuation_activity( reference), reference, ) context = TurnContext(self, request) return await self.run_pipeline(context, callback)
async def test_on_reply_to_activity(self): self._conversation_id = await self._test_id_factory.create_skill_conversation_id( self._conversation_reference) mock_adapter = Mock() mock_adapter.continue_conversation = MagicMock(return_value=Future()) mock_adapter.continue_conversation.return_value.set_result(Mock()) mock_adapter.send_activities = MagicMock(return_value=Future()) mock_adapter.send_activities.return_value.set_result([]) sut = self.create_skill_handler_for_testing(mock_adapter) activity = Activity(type=ActivityTypes.message, attachments=[], entities=[]) activity_id = str(uuid4()) TurnContext.apply_conversation_reference(activity, self._conversation_reference) await sut.test_on_reply_to_activity(self._claims_identity, self._conversation_id, activity_id, activity) args, kwargs = mock_adapter.continue_conversation.call_args_list[0] assert isinstance(args[0], ConversationReference) assert callable(args[1]) assert isinstance(kwargs["claims_identity"], ClaimsIdentity) await args[1](TurnContext( mock_adapter, conversation_reference_extension.get_continuation_activity( self._conversation_reference), )) assert activity.caller_id is None
async def continue_conversation( self, reference: ConversationReference, callback: Callable, bot_id: str = None, claims_identity: ClaimsIdentity = None, audience: str = None, ): """ Sends a proactive message to a conversation. Call this method to proactively send a message to a conversation. Most _channels require a user to initiate a conversation with a bot before the bot can send activities to the user. :param bot_id: Unused for this override. :param reference: A reference to the conversation to continue. :param callback: The method to call for the resulting bot turn. :param claims_identity: A ClaimsIdentity for the conversation. :param audience: Unused for this override. """ if not reference: raise Exception("ConversationReference is required") if not callback: raise Exception("callback is required") if claims_identity: request = conversation_reference_extension.get_continuation_activity( reference ) context = TurnContext(self, request) context.turn_state[BotAdapter.BOT_IDENTITY_KEY] = claims_identity context.turn_state[BotAdapter.BOT_CALLBACK_HANDLER_KEY] = callback else: request = TurnContext.apply_conversation_reference( conversation_reference_extension.get_continuation_activity(reference), reference, ) context = TurnContext(self, request) return await self.run_pipeline(context, callback)
async def continue_conversation( reference: ConversationReference, callback: Callable, bot_id: str = None, claims_identity: ClaimsIdentity = None, audience: str = None, ): # pylint: disable=unused-argument # Invoke the callback created by the handler so we can assert the rest of the execution. turn_context = TurnContext( mock_adapter, conversation_reference_extension.get_continuation_activity( conversation_reference ), ) await callback(turn_context)
async def continue_conversation( reference: ConversationReference, callback: Callable, bot_id: str = None, claims_identity: ClaimsIdentity = None, audience: str = None, ): # pylint: disable=unused-argument # Invoke the callback created by the handler so we can assert the rest of the execution. turn_context = TurnContext( mock_adapter, conversation_reference_extension.get_continuation_activity( self._conversation_reference), ) await callback(turn_context) # Assert the callback set the right properties. assert (f"{CallerIdConstants.bot_to_bot_prefix}{self.skill_id}" ), turn_context.activity.caller_id
async def test_on_reply_to_activity(self): resource_response_id = "resourceId" self._conversation_id = await self._test_id_factory.create_skill_conversation_id( self._conversation_reference) types_to_test = [ ActivityTypes.end_of_conversation, ActivityTypes.event, ActivityTypes.message, ] for activity_type in types_to_test: with self.subTest(act_type=activity_type): mock_adapter = Mock() mock_adapter.continue_conversation = MagicMock( return_value=Future()) mock_adapter.continue_conversation.return_value.set_result( Mock()) mock_adapter.send_activities = MagicMock(return_value=Future()) mock_adapter.send_activities.return_value.set_result( [ResourceResponse(id=resource_response_id)]) sut = self.create_skill_handler_for_testing(mock_adapter) activity = Activity(type=activity_type, attachments=[], entities=[]) activity_id = str(uuid4()) TurnContext.apply_conversation_reference( activity, self._conversation_reference) resource_response = await sut.test_on_reply_to_activity( self._claims_identity, self._conversation_id, activity_id, activity) # continue_conversation validation ( args_continue, kwargs_continue, ) = mock_adapter.continue_conversation.call_args_list[0] mock_adapter.continue_conversation.assert_called_once() assert isinstance(args_continue[0], ConversationReference) assert callable(args_continue[1]) assert isinstance(kwargs_continue["claims_identity"], ClaimsIdentity) turn_context = TurnContext( mock_adapter, conversation_reference_extension.get_continuation_activity( self._conversation_reference), ) await args_continue[1](turn_context) # assert the callback set the right properties. assert (f"{CallerIdConstants.bot_to_bot_prefix}{self.skill_id}" ), turn_context.activity.caller_id if activity_type == ActivityTypes.message: # send_activities validation ( args_send, _, ) = mock_adapter.send_activities.call_args_list[0] activity_from_send = args_send[1][0] assert activity_from_send.caller_id is None assert activity_from_send.reply_to_id, activity_id assert resource_response.id, resource_response_id else: # Assert mock SendActivitiesAsync wasn't called mock_adapter.send_activities.assert_not_called()