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
Exemplo n.º 2
0
    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
Exemplo n.º 3
0
    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
Exemplo n.º 4
0
    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)
Exemplo n.º 5
0
    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)
Exemplo n.º 6
0
    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