async def post_activity( self, from_bot_id: str, to_bot_id: str, to_url: str, service_url: str, conversation_id: str, activity: Activity, ) -> InvokeResponse: app_credentials = await self._get_app_credentials( from_bot_id, to_bot_id) if not app_credentials: raise KeyError( "Unable to get appCredentials to connect to the skill") # Get token for the skill call token = (app_credentials.get_access_token() if app_credentials.microsoft_app_id else None) # Capture current activity settings before changing them. original_conversation_id = activity.conversation.id original_service_url = activity.service_url original_relates_to = activity.relates_to original_recipient = activity.recipient try: activity.relates_to = ConversationReference( service_url=activity.service_url, activity_id=activity.id, channel_id=activity.channel_id, conversation=ConversationAccount( id=activity.conversation.id, name=activity.conversation.name, conversation_type=activity.conversation.conversation_type, aad_object_id=activity.conversation.aad_object_id, is_group=activity.conversation.is_group, role=activity.conversation.role, tenant_id=activity.conversation.tenant_id, properties=activity.conversation.properties, ), bot=None, ) activity.conversation.id = conversation_id activity.service_url = service_url if not activity.recipient: activity.recipient = ChannelAccount(role=RoleTypes.skill) else: activity.recipient.role = RoleTypes.skill status, content = await self._post_content(to_url, token, activity) return InvokeResponse(status=status, body=content) finally: # Restore activity properties. activity.conversation.id = original_conversation_id activity.service_url = original_service_url activity.relates_to = original_relates_to activity.recipient = original_recipient
async def post_activity( self, from_bot_id: str, to_bot_id: str, to_url: str, service_url: str, conversation_id: str, activity: Activity, ) -> InvokeResponse: app_credentials = await self._get_app_credentials( from_bot_id, to_bot_id) if not app_credentials: raise KeyError( "Unable to get appCredentials to connect to the skill") # Get token for the skill call token = (app_credentials.get_access_token() if app_credentials.microsoft_app_id else None) # Capture current activity settings before changing them. # TODO: DO we need to set the activity ID? (events that are created manually don't have it). original_conversation_id = activity.conversation.id original_service_url = activity.service_url original_caller_id = activity.caller_id try: activity.conversation.id = conversation_id activity.service_url = service_url activity.caller_id = from_bot_id headers_dict = { "Content-type": "application/json; charset=utf-8", } if token: headers_dict.update({ "Authorization": f"Bearer {token}", }) json_content = json.dumps(activity.serialize()) resp = await self._session.post( to_url, data=json_content.encode("utf-8"), headers=headers_dict, ) resp.raise_for_status() data = (await resp.read()).decode() content = json.loads(data) if data else None if content: return InvokeResponse(status=resp.status, body=content) finally: # Restore activity properties. activity.conversation.id = original_conversation_id activity.service_url = original_service_url activity.caller_id = original_caller_id
def apply_conversation_reference(activity: Activity, reference: ConversationReference, is_incoming: bool = False) -> Activity: """ Updates an activity with the delivery information from a conversation reference. Calling this after get_conversation_reference on an incoming activity will properly address the reply to a received activity. :param activity: :param reference: :param is_incoming: :return: """ activity.channel_id = reference.channel_id activity.service_url = reference.service_url activity.conversation = reference.conversation if is_incoming: activity.from_property = reference.user activity.recipient = reference.bot if reference.activity_id: activity.id = reference.activity_id else: activity.from_property = reference.bot activity.recipient = reference.user if reference.activity_id: activity.reply_to_id = reference.activity_id return activity
async def on_send_to_conversation( self, claims_identity: ClaimsIdentity, conversation_id: str, activity: Activity, ) -> ResourceResponse: back_conversation_id, back_service_url = self._factory.get_conversation_info(conversation_id) connector_client = self._get_connector_client(back_service_url) activity.conversation.id = back_conversation_id activity.service_url = back_service_url return await connector_client.conversations.send_to_conversation(back_conversation_id, activity)
async def process_activity(self, activity: Activity, logic: Callable[[TurnContext], Awaitable]): self._conversation_lock.acquire() try: # ready for next reply if activity.type is None: activity.type = ActivityTypes.message activity.channel_id = self.template.channel_id activity.from_property = self.template.from_property activity.recipient = self.template.recipient activity.conversation = self.template.conversation activity.service_url = self.template.service_url activity.id = str((self._next_id)) self._next_id += 1 finally: self._conversation_lock.release() activity.timestamp = activity.timestamp or datetime.utcnow() await self.run_pipeline(TurnContext(self, activity), logic)
async def post_activity( self, from_bot_id: str, to_bot_id: str, to_url: str, service_url: str, conversation_id: str, activity: Activity, ) -> InvokeResponse: app_credentials = await self._get_app_credentials( from_bot_id, to_bot_id) if not app_credentials: raise KeyError( "Unable to get appCredentials to connect to the skill") # Get token for the skill call token = (app_credentials.get_access_token() if app_credentials.microsoft_app_id else None) # Capture current activity settings before changing them. # TODO: DO we need to set the activity ID? (events that are created manually don't have it). original_conversation_id = activity.conversation.id original_service_url = activity.service_url original_caller_id = activity.caller_id original_relates_to = activity.relates_to try: # TODO: The relato has to be ported to the adapter in the new integration library when # resolving conflicts in merge activity.relates_to = ConversationReference( service_url=activity.service_url, activity_id=activity.id, channel_id=activity.channel_id, conversation=ConversationAccount( id=activity.conversation.id, name=activity.conversation.name, conversation_type=activity.conversation.conversation_type, aad_object_id=activity.conversation.aad_object_id, is_group=activity.conversation.is_group, role=activity.conversation.role, tenant_id=activity.conversation.tenant_id, properties=activity.conversation.properties, ), bot=None, ) activity.conversation.id = conversation_id activity.service_url = service_url activity.caller_id = f"urn:botframework:aadappid:{from_bot_id}" headers_dict = { "Content-type": "application/json; charset=utf-8", } if token: headers_dict.update({ "Authorization": f"Bearer {token}", }) json_content = json.dumps(activity.serialize()) resp = await self._session.post( to_url, data=json_content.encode("utf-8"), headers=headers_dict, ) resp.raise_for_status() data = (await resp.read()).decode() content = json.loads(data) if data else None return InvokeResponse(status=resp.status, body=content) finally: # Restore activity properties. activity.conversation.id = original_conversation_id activity.service_url = original_service_url activity.caller_id = original_caller_id activity.relates_to = original_relates_to