def create_activities(self,
                       conversation_id: str,
                       date: datetime,
                       count: int = 5):
     activities: List[Activity] = []
     time_stamp = date
     for i in range(count):
         activities.append(
             Activity(
                 type=ActivityTypes.message,
                 timestamp=time_stamp,
                 id=str(uuid.uuid4()),
                 text=str(i),
                 channel_id="test",
                 from_property=ChannelAccount(id=f"User{i}"),
                 conversation=ConversationAccount(id=conversation_id),
                 recipient=ChannelAccount(id="bot1", name="2"),
                 service_url="http://foo.com/api/messages",
             ))
         time_stamp = time_stamp + datetime.timedelta(0, 60)
         activities.append(
             Activity(
                 type=ActivityTypes.message,
                 timestamp=date,
                 id=str(uuid.uuid4()),
                 text=str(i),
                 channel_id="test",
                 from_property=ChannelAccount(id="Bot1", name="2"),
                 conversation=ConversationAccount(id=conversation_id),
                 recipient=ChannelAccount(id=f"User{i}"),
                 service_url="http://foo.com/api/messages",
             ))
         time_stamp = time_stamp + datetime.timedelta(
             0, 60)  # days, seconds, then other fields.
     return activities
Ejemplo n.º 2
0
    def __init__(self,
                 logic: Coroutine = None,
                 template: ConversationReference = None):
        """
        Creates a new TestAdapter instance.
        :param logic:
        :param template:
        """
        super(TestAdapter, self).__init__()
        self.logic = logic
        self._next_id: int = 0
        self.activity_buffer: List[Activity] = []
        self.updated_activities: List[Activity] = []
        self.deleted_activities: List[ConversationReference] = []

        self.template: Activity = Activity(
            channel_id='test',
            service_url='https://test.com',
            from_property=ChannelAccount(id='User1', name='user'),
            recipient=ChannelAccount(id='bot', name='Bot'),
            conversation=ConversationAccount(id='Convo1'))
        if template is not None:
            self.template.service_url = template.service_url
            self.template.conversation = template.conversation
            self.template.channel_id = template.channel_id
Ejemplo n.º 3
0
    def __init__(
        self,
        logic: Coroutine = None,
        conversation: ConversationReference = None,
        send_trace_activity: bool = False,
    ):  # pylint: disable=unused-argument
        """
        Creates a new TestAdapter instance.
        :param logic:
        :param conversation: A reference to the conversation to begin the adapter state with.
        """
        super(TestAdapter, self).__init__()
        self.logic = logic
        self._next_id: int = 0
        self._user_tokens: List[UserToken] = []
        self._magic_codes: List[TokenMagicCode] = []
        self.activity_buffer: List[Activity] = []
        self.updated_activities: List[Activity] = []
        self.deleted_activities: List[ConversationReference] = []

        self.template: Activity = Activity(
            channel_id="test",
            service_url="https://test.com",
            from_property=ChannelAccount(id="User1", name="user"),
            recipient=ChannelAccount(id="bot", name="Bot"),
            conversation=ConversationAccount(id="Convo1"),
        )
        if self.template is not None:
            self.template.service_url = self.template.service_url
            self.template.conversation = self.template.conversation
            self.template.channel_id = self.template.channel_id
    async def test_does_not_overwrite_non_null_recipient_values(self):
        skill_recipient_id = "skillBot"
        mock_credential_provider = Mock(spec=CredentialProvider)

        # pylint: disable=unused-argument
        async def _mock_post_content(to_url: str, token: str,
                                     activity: Activity) -> (int, object):
            nonlocal self
            self.assertIsNotNone(activity.recipient)
            self.assertEqual(skill_recipient_id, activity.recipient.id)
            return 200, None

        client = BotFrameworkHttpClient(
            credential_provider=mock_credential_provider)
        client._post_content = _mock_post_content  # pylint: disable=protected-access

        activity = Activity(
            conversation=ConversationAccount(),
            recipient=ChannelAccount(id=skill_recipient_id),
        )

        await client.post_activity(
            None,
            None,
            "https://skillbot.com/api/messages",
            "https://parentbot.com/api/messages",
            "NewConversationId",
            activity,
        )

        assert activity.recipient.id == skill_recipient_id
        assert activity.recipient.role is RoleTypes.skill
    async def create_conversation(self, reference: ConversationReference, logic: Callable[[TurnContext], Awaitable]=None):
        """
        Starts a new conversation with a user. This is typically used to Direct Message (DM) a member
        of a group.
        :param reference:
        :param logic:
        :return:
        """
        try:
            if reference.service_url is None:
                raise TypeError('BotFrameworkAdapter.create_conversation(): reference.service_url cannot be None.')

            # Create conversation
            parameters = ConversationParameters(bot=reference.bot)
            client = self.create_connector_client(reference.service_url)

            # Mix in the tenant ID if specified. This is required for MS Teams.
            if reference.conversation is not None and reference.conversation.tenant_id:
                # Putting tenant_id in channel_data is a temporary while we wait for the Teams API to be updated
                parameters.channel_data = {'tenant': {'id': reference.conversation.tenant_id}}

                # Permanent solution is to put tenant_id in parameters.tenant_id
                parameters.tenant_id = reference.conversation.tenant_id

            resource_response = await client.conversations.create_conversation(parameters)
            request = TurnContext.apply_conversation_reference(Activity(), reference, is_incoming=True)
            request.conversation = ConversationAccount(id=resource_response.id)
            if resource_response.service_url:
                request.service_url = resource_response.service_url

            context = self.create_context(request)
            return await self.run_pipeline(context, logic)

        except Exception as e:
            raise e
    async def test_adds_recipient_and_sets_it_back_to_null(self):
        mock_credential_provider = Mock(spec=CredentialProvider)

        # pylint: disable=unused-argument
        async def _mock_post_content(to_url: str, token: str,
                                     activity: Activity) -> (int, object):
            nonlocal self
            self.assertIsNotNone(activity.recipient)
            return 200, None

        client = BotFrameworkHttpClient(
            credential_provider=mock_credential_provider)
        client._post_content = _mock_post_content  # pylint: disable=protected-access

        activity = Activity(conversation=ConversationAccount())

        await client.post_activity(
            None,
            None,
            "https://skillbot.com/api/messages",
            "https://parentbot.com/api/messages",
            "NewConversationId",
            activity,
        )

        assert activity.recipient is None
    async def test_bot_on_teams_members_added_activity(self):
        # arrange
        activity = Activity(
            recipient=ChannelAccount(id="botid"),
            type=ActivityTypes.conversation_update,
            channel_data={
                "eventType": "teamMemberAdded",
                "team": {
                    "id": "team_id_1",
                    "name": "new_team_name"
                },
            },
            members_added=[
                ChannelAccount(
                    id="botid",
                    name="test_user",
                    aad_object_id="asdfqwerty",
                    role="tester",
                )
            ],
            channel_id=Channels.ms_teams,
            conversation=ConversationAccount(id="456"),
        )

        turn_context = TurnContext(SimpleAdapter(), activity)

        # Act
        bot = TestingTeamsActivityHandler()
        await bot.on_turn(turn_context)

        # Assert
        assert len(bot.record) == 2
        assert bot.record[0] == "on_conversation_update_activity"
        assert bot.record[1] == "on_teams_members_added"
Ejemplo n.º 8
0
def create_activity_reply(activity: Activity,
                          text: str = None,
                          locale: str = None,
                          attachments=None):
    if attachments is None:
        attachments = []
    attachments_aux = attachments.copy()

    return Activity(
        type=ActivityTypes.message,
        timestamp=datetime.utcnow(),
        from_property=ChannelAccount(
            id=getattr(activity.recipient, "id", None),
            name=getattr(activity.recipient, "name", None),
        ),
        recipient=ChannelAccount(id=activity.from_property.id,
                                 name=activity.from_property.name),
        reply_to_id=activity.id,
        service_url=activity.service_url,
        channel_id=activity.channel_id,
        conversation=ConversationAccount(
            is_group=activity.conversation.is_group,
            id=activity.conversation.id,
            name=activity.conversation.name,
        ),
        text=text or "",
        locale=locale or "",
        attachments=attachments_aux,
        entities=[],
    )
Ejemplo n.º 9
0
    async def process_activity(self, logic: Callable):
        """
        Begins listening to console input.
        :param logic:
        :return:
        """
        while True:
            msg = input()
            if msg is None:
                pass
            else:
                self._next_id += 1
                activity = Activity(
                    text=msg,
                    channel_id="console",
                    from_property=ChannelAccount(id="user", name="User1"),
                    recipient=ChannelAccount(id="bot", name="Bot"),
                    conversation=ConversationAccount(id="Convo1"),
                    type=ActivityTypes.message,
                    timestamp=datetime.datetime.now(),
                    id=str(self._next_id),
                )

                activity = TurnContext.apply_conversation_reference(
                    activity, self.reference, True)
                context = TurnContext(self, activity)
                await self.run_pipeline(context, logic)
Ejemplo n.º 10
0
 async def process_activity(self, logic: Callable):
     """
     Begins listening to console input.
     :param logic:
     :return:
     """
     while True:
         #user's input is set as variable msg
         msg = input()
         #Nothing happens if the user inputs a blank input
         if msg is None:
             pass
         else:
             #increases _next_id value by one
             self._next_id += 1
             # creating an object for communication with the Bot. Used as an initial message for a new conversation
             activity = Activity(
                 text=msg,
                 channel_id='console',
                 #Uniquely identifies ID of user and their name
                 from_property=ChannelAccount(id='user', name='User1'),
                 #identifies the bot as recipient and their name as Bot
                 recipient=ChannelAccount(id='bot', name='Bot'),
                 #identification of the conversation
                 conversation=ConversationAccount(id='Convo1'),
                 type=ActivityTypes.message,
                 timestamp=datetime.datetime.now(),
                 id=str(self._next_id))
             #send to the bot
             activity = TurnContext.apply_conversation_reference(
                 activity, self.reference, True)
             context = TurnContext(self, activity)
             # output of the function
             #logs message from user
             await self.run_middleware(context, logic)
Ejemplo n.º 11
0
    def test_apply_conversation_reference_with_is_incoming_true(self):
        # Arrange
        activity = self.__create_activity()
        conversation_reference = ConversationReference(
            channel_id="cr_123",
            service_url="cr_serviceUrl",
            conversation=ConversationAccount(id="cr_456"),
            user=ChannelAccount(id="cr_abc"),
            bot=ChannelAccount(id="cr_def"),
            activity_id="cr_12345",
            locale="en-uS",
        )

        # Act
        activity.apply_conversation_reference(reference=conversation_reference,
                                              is_incoming=True)

        # Assert
        self.assertEqual(conversation_reference.channel_id,
                         activity.channel_id)
        self.assertEqual(conversation_reference.locale, activity.locale)
        self.assertEqual(conversation_reference.service_url,
                         activity.service_url)
        self.assertEqual(conversation_reference.conversation.id,
                         activity.conversation.id)
        self.assertEqual(conversation_reference.user.id,
                         activity.from_property.id)
        self.assertEqual(conversation_reference.bot.id, activity.recipient.id)
        self.assertEqual(conversation_reference.activity_id, activity.id)
Ejemplo n.º 12
0
    async def process_activities(self, msgs, logic: Callable):
        """
        Loops through array of strings to bot

        :param msgs:
        :param logic:
        :return:
        """
        for msg in msgs:
            if msg is None:
                pass
            else:
                self._next_id += 1
                activity = Activity(text=msg,
                                    channel_id='console',
                                    from_property=ChannelAccount(id='user', name='User1'),
                                    recipient=ChannelAccount(id='bot', name='Bot'),
                                    conversation=ConversationAccount(id='Convo1'),
                                    type=ActivityTypes.message,
                                    timestamp=datetime.datetime.now(),
                                    id=str(self._next_id))

                activity = TurnContext.apply_conversation_reference(activity, self.reference, True)
                context = TurnContext(self, activity)
                print(context.get_conversation_reference(activity))

                await self.run_middleware(context, logic)
Ejemplo n.º 13
0
    def payload_to_activity(payload: SlackPayload) -> Activity:
        """
        Creates an activity based on the Slack event payload.

        :param payload: The payload of the Slack event.
        :type payload: :class:`SlackPayload`
        :return: An activity containing the event data.
        :rtype: :class:`botbuilder.schema.Activity`
        """

        if not payload:
            raise Exception("payload is required")

        activity = Activity(
            channel_id="slack",
            conversation=ConversationAccount(id=payload.channel.id,
                                             properties={}),
            from_property=ChannelAccount(id=payload.message.bot_id if payload.
                                         message.bot_id else payload.user.id),
            recipient=ChannelAccount(),
            channel_data=payload,
            text=None,
            type=ActivityTypes.event,
        )

        if payload.thread_ts:
            activity.conversation.properties["thread_ts"] = payload.thread_ts

        if payload.actions and (payload.type == "block_actions"
                                or payload.type == "interactive_message"):
            activity.type = ActivityTypes.message
            activity.text = payload.actions.value

        return activity
Ejemplo n.º 14
0
    def __create_activity() -> Activity:
        account1 = ChannelAccount(
            id="ChannelAccount_Id_1",
            name="ChannelAccount_Name_1",
            aad_object_id="ChannelAccount_aadObjectId_1",
            role="ChannelAccount_Role_1",
        )

        account2 = ChannelAccount(
            id="ChannelAccount_Id_2",
            name="ChannelAccount_Name_2",
            aad_object_id="ChannelAccount_aadObjectId_2",
            role="ChannelAccount_Role_2",
        )

        conversation_account = ConversationAccount(
            conversation_type="a",
            id="123",
            is_group=True,
            name="Name",
            role="ConversationAccount_Role",
        )

        activity = Activity(
            id="123",
            from_property=account1,
            recipient=account2,
            conversation=conversation_account,
            channel_id="ChannelId123",
            locale="en-uS",
            service_url="ServiceUrl123",
        )

        return activity
Ejemplo n.º 15
0
    async def test_bot_state_delete(self):
        # pylint: disable=unnecessary-lambda
        turn_context = TestUtilities.create_empty_context()
        turn_context.activity.conversation = ConversationAccount(id="1234")

        storage = MemoryStorage({})

        # Turn 0
        bot_state1 = ConversationState(storage)
        (await bot_state1.create_property("test-name").get(
            turn_context, lambda: TestPocoState())).value = "test-value"
        await bot_state1.save_changes(turn_context)

        # Turn 1
        bot_state2 = ConversationState(storage)
        value1 = (await bot_state2.create_property("test-name").get(
            turn_context, lambda: TestPocoState(value="default-value"))).value

        assert value1 == "test-value"

        # Turn 2
        bot_state3 = ConversationState(storage)
        await bot_state3.delete(turn_context)

        # Turn 3
        bot_state4 = ConversationState(storage)
        value2 = (await bot_state4.create_property("test-name").get(
            turn_context, lambda: TestPocoState(value="default-value"))).value

        assert value2 == "default-value"
Ejemplo n.º 16
0
    def __init__(self, logic: Coroutine = None, conversation: ConversationReference = None,
                 send_trace_activity: bool = False):
        """
        Creates a new TestAdapter instance.
        :param logic:
        :param conversation: A reference to the conversation to begin the adapter state with.
        """
        super(TestAdapter, self).__init__()
        self.logic = logic
        self._next_id: int = 0
        self._user_tokens: List[UserToken] = []
        self._magic_codes: List[TokenMagicCode] = []
        self.activity_buffer: List[Activity] = []
        self.updated_activities: List[Activity] = []
        self.deleted_activities: List[ConversationReference] = []

        self.template: Activity = Activity(
            channel_id='test',
            service_url='https://test.com',
            from_property=ChannelAccount(id='User1', name='user'),
            recipient=ChannelAccount(id='bot', name='Bot'),
            conversation=ConversationAccount(id='Convo1')
        )
        if self.template is not None:
            self.template.service_url = self.template.service_url
            self.template.conversation = self.template.conversation
            self.template.channel_id = self.template.channel_id
    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
Ejemplo n.º 18
0
    async def command_to_activity(body: SlackRequestBody,
                                  client: SlackClient) -> Activity:
        """
        Creates an activity based on a Slack event related to a slash command.

        :param body: The data of the Slack event.
        :type body: :class:`SlackRequestBody`
        :param client: The Slack client.
        :type client: :class:`SlackClient`
        :return: An activity containing the event data.
        :rtype: :class:`botbuilder.schema.Activity`
        """

        if not body:
            raise Exception("body is required")

        activity = Activity(
            id=body.trigger_id,
            channel_id="slack",
            conversation=ConversationAccount(id=body.channel_id,
                                             properties={}),
            from_property=ChannelAccount(id=body.user_id),
            recipient=ChannelAccount(id=None),
            channel_data=body,
            text=body.text,
            type=ActivityTypes.event,
            name="Command",
            value=body.command,
        )

        activity.recipient.id = await client.get_bot_user_identity(activity)
        activity.conversation.properties["team"] = body.team_id

        return activity
Ejemplo n.º 19
0
    def __init__(self, reference: ConversationReference = None):
        super(ConsoleAdapter, self).__init__()

        self.reference = ConversationReference(
            channel_id='console',
            user=ChannelAccount(id='user', name='User1'),
            bot=ChannelAccount(id='bot', name='Bot'),
            conversation=ConversationAccount(id='convo1',
                                             name='',
                                             is_group=False),
            service_url='')

        # Warn users to pass in an instance of a ConversationReference, otherwise the parameter will be ignored.
        if reference is not None and not isinstance(reference,
                                                    ConversationReference):
            warnings.warn(
                'ConsoleAdapter: `reference` argument is not an instance of ConversationReference and will '
                'be ignored.')
        else:
            self.reference.channel_id = getattr(reference, 'channel_id',
                                                self.reference.channel_id)
            self.reference.user = getattr(reference, 'user',
                                          self.reference.user)
            self.reference.bot = getattr(reference, 'bot', self.reference.bot)
            self.reference.conversation = getattr(reference, 'conversation',
                                                  self.reference.conversation)
            self.reference.service_url = getattr(reference, 'service_url',
                                                 self.reference.service_url)
            # The only attribute on self.reference without an initial value is activity_id, so if reference does not
            # have a value for activity_id, default self.reference.activity_id to None
            self.reference.activity_id = getattr(reference, 'activity_id',
                                                 None)

        self._next_id = 0
Ejemplo n.º 20
0
    def __init__(self, reference: ConversationReference = None):
        super(ConsoleAdapter, self).__init__()

        self.reference = ConversationReference(
            channel_id="console",
            user=ChannelAccount(id="user", name="User1"),
            bot=ChannelAccount(id="bot", name="Bot"),
            conversation=ConversationAccount(id="convo1",
                                             name="",
                                             is_group=False),
            service_url="",
        )

        # Warn users to pass in an instance of a ConversationReference, otherwise the parameter will be ignored.
        if reference is not None and not isinstance(reference,
                                                    ConversationReference):
            warnings.warn(
                "ConsoleAdapter: `reference` argument is not an instance of ConversationReference and will "
                "be ignored.")
        else:
            self.reference.channel_id = getattr(reference, "channel_id",
                                                self.reference.channel_id)
            self.reference.user = getattr(reference, "user",
                                          self.reference.user)
            self.reference.bot = getattr(reference, "bot", self.reference.bot)
            self.reference.conversation = getattr(reference, "conversation",
                                                  self.reference.conversation)
            self.reference.service_url = getattr(reference, "service_url",
                                                 self.reference.service_url)
            # The only attribute on self.reference without an initial value is activity_id, so if reference does not
            # have a value for activity_id, default self.reference.activity_id to None
            self.reference.activity_id = getattr(reference, "activity_id",
                                                 None)

        self._next_id = 0
    async def test_clear_and_save(self):
        turn_context = TestUtilities.create_empty_context()
        turn_context.activity.conversation = ConversationAccount(id="1234")

        storage = MemoryStorage({})

        # Turn 0
        bot_state1 = ConversationState(storage)
        (await bot_state1.create_property("test-name").get(
            turn_context, lambda: TestPocoState())).value = "test-value"
        await bot_state1.save_changes(turn_context)

        # Turn 1
        bot_state2 = ConversationState(storage)
        value1 = (await bot_state2.create_property("test-name").get(
            turn_context, lambda: TestPocoState(value="default-value"))).value

        assert "test-value" == value1

        # Turn 2
        bot_state3 = ConversationState(storage)
        await bot_state3.clear_state(turn_context)
        await bot_state3.save_changes(turn_context)

        # Turn 3
        bot_state4 = ConversationState(storage)
        value2 = (await bot_state4.create_property("test-name").get(
            turn_context, lambda: TestPocoState(value="default-value"))).value

        assert "default-value", value2
Ejemplo n.º 22
0
async def process_activity(
    channel_id: str, channel_data_tenant_id: str, conversation_tenant_id: str
):
    activity = None
    mock_claims = unittest.mock.create_autospec(ClaimsIdentity)
    mock_credential_provider = unittest.mock.create_autospec(
        BotFrameworkAdapterSettings
    )

    sut = BotFrameworkAdapter(mock_credential_provider)

    async def aux_func(context):
        nonlocal activity
        activity = context.Activity

    await sut.process_activity(
        Activity(
            channel_id=channel_id,
            service_url="https://smba.trafficmanager.net/amer/",
            channel_data={"tenant": {"id": channel_data_tenant_id}},
            conversation=ConversationAccount(tenant_id=conversation_tenant_id),
        ),
        mock_claims,
        aux_func,
    )
    return activity
Ejemplo n.º 23
0
    async def create_conversation(self, reference: ConversationReference,
                                  logic):
        """
        Starts a new conversation with a user. This is typically used to Direct Message (DM) a member
        of a group.
        :param reference:
        :param logic:
        :return:
        """
        try:
            if reference.service_url is None:
                raise TypeError(
                    'BotFrameworkAdapter.create_conversation(): reference.service_url cannot be None.'
                )

            # Create conversation
            parameters = ConversationParameters(bot=reference.bot)
            client = self.create_connector_client(reference.service_url)

            resource_response = await client.conversations.create_conversation(
                parameters)
            request = TurnContext.apply_conversation_reference(
                Activity(), reference, is_incoming=True)
            request.conversation = ConversationAccount(id=resource_response.id)
            if resource_response.service_url:
                request.service_url = resource_response.service_url

            context = self.create_context(request)
            return await self.run_middleware(context, logic)

        except Exception as e:
            raise e
Ejemplo n.º 24
0
    async def test_continue_conversation_direct_msg(self):
        callback_invoked = False
        adapter = TestAdapter()
        reference = ConversationReference(
            activity_id="activityId",
            bot=ChannelAccount(id="channelId",
                               name="testChannelAccount",
                               role="bot"),
            channel_id="testChannel",
            service_url="testUrl",
            conversation=ConversationAccount(
                conversation_type="",
                id="testConversationId",
                is_group=False,
                name="testConversationName",
                role="user",
            ),
            user=ChannelAccount(id="channelId",
                                name="testChannelAccount",
                                role="bot"),
        )

        async def continue_callback(turn_context):  # pylint: disable=unused-argument
            nonlocal callback_invoked
            callback_invoked = True

        await adapter.continue_conversation(reference, continue_callback,
                                            "MyBot")
        self.assertTrue(callback_invoked)
Ejemplo n.º 25
0
    def setUpClass(cls):
        cls.bot_id = str(uuid4())
        cls.skill_id = str(uuid4())

        cls._test_id_factory = ConversationIdFactoryForTest()

        cls._claims_identity = ClaimsIdentity({}, False)

        cls._claims_identity.claims[AuthenticationConstants.AUDIENCE_CLAIM] = cls.bot_id
        cls._claims_identity.claims[AuthenticationConstants.APP_ID_CLAIM] = cls.skill_id
        cls._claims_identity.claims[
            AuthenticationConstants.SERVICE_URL_CLAIM
        ] = "http://testbot.com/api/messages"
        cls._conversation_reference = ConversationReference(
            conversation=ConversationAccount(id=str(uuid4())),
            service_url="http://testbot.com/api/messages",
        )
        activity = Activity.create_message_activity()
        activity.apply_conversation_reference(cls._conversation_reference)
        skill = BotFrameworkSkill(
            app_id=cls.skill_id,
            id="skill",
            skill_endpoint="http://testbot.com/api/messages",
        )
        cls._options = SkillConversationIdFactoryOptions(
            from_bot_oauth_scope=cls.bot_id,
            from_bot_id=cls.bot_id,
            activity=activity,
            bot_framework_skill=skill,
        )
Ejemplo n.º 26
0
    def __init__(
        self,
        logic: Coroutine = None,
        template_or_conversation: Union[Activity,
                                        ConversationReference] = None,
        send_trace_activities: bool = False,
    ):
        """
        Creates a new TestAdapter instance.
        :param logic:
        :param conversation: A reference to the conversation to begin the adapter state with.
        """
        super(TestAdapter, self).__init__()
        self.logic = logic
        self._next_id: int = 0
        self._user_tokens: List[UserToken] = []
        self._magic_codes: List[TokenMagicCode] = []
        self._conversation_lock = Lock()
        self.exchangeable_tokens: Dict[str, ExchangeableToken] = {}
        self.activity_buffer: List[Activity] = []
        self.updated_activities: List[Activity] = []
        self.deleted_activities: List[ConversationReference] = []
        self.send_trace_activities = send_trace_activities

        self.template = (template_or_conversation if isinstance(
            template_or_conversation, Activity) else Activity(
                channel_id="test",
                service_url="https://test.com",
                from_property=ChannelAccount(id="User1", name="user"),
                recipient=ChannelAccount(id="bot", name="Bot"),
                conversation=ConversationAccount(id="Convo1"),
            ))

        if isinstance(template_or_conversation, ConversationReference):
            self.template.channel_id = template_or_conversation.channel_id
Ejemplo n.º 27
0
 def send_message(self, text, channel_type, mentions=None):
     if channel_type in self._conversation_channels:
         channel_id = self._conversation_channels[channel_type]
     else:
         channel_id = self._channel_data['channel']['id']
     conversation = ConversationAccount(is_group=True, id=channel_id, conversation_type="channel")
     self.__send(text, conversation, mentions)
Ejemplo n.º 28
0
    async def test_process_activity_with_identity_token_exchange_invoke_response(
            self):
        mock_credential_provider = unittest.mock.create_autospec(
            CredentialProvider)

        settings = BotFrameworkAdapterSettings(
            app_id="bot_id",
            credential_provider=mock_credential_provider,
        )
        adapter = AdapterUnderTest(settings)

        identity = ClaimsIdentity(
            claims={
                AuthenticationConstants.AUDIENCE_CLAIM: "bot_id",
                AuthenticationConstants.APP_ID_CLAIM: "bot_id",
                AuthenticationConstants.VERSION_CLAIM: "1.0",
            },
            is_authenticated=True,
        )

        inbound_activity = Activity(
            type=ActivityTypes.invoke,
            name=SignInConstants.token_exchange_operation_name,
            service_url="http://tempuri.org/whatever",
            delivery_mode=DeliveryModes.normal,
            conversation=ConversationAccount(id="conversationId"),
            value=TokenExchangeInvokeRequest(
                id="token_exchange_id",
                token="token",
                connection_name="connection_name",
            ),
        )

        async def callback(context: TurnContext):
            activity = Activity(
                type=ActivityTypes.invoke_response,
                value=InvokeResponse(
                    status=200,
                    body=TokenExchangeInvokeResponse(
                        id=context.activity.value.id,
                        connection_name=context.activity.value.connection_name,
                    ),
                ),
            )

            await context.send_activity(activity)

        invoke_response = await adapter.process_activity_with_identity(
            inbound_activity,
            identity,
            callback,
        )

        assert invoke_response
        assert invoke_response.status == 200
        assert invoke_response.body["id"] == inbound_activity.value.id
        assert (invoke_response.body["connectionName"] ==
                inbound_activity.value.connection_name)
Ejemplo n.º 29
0
 def _get_context(utterance: str, bot_adapter: BotAdapter) -> TurnContext:
     activity = Activity(
         type=ActivityTypes.message,
         text=utterance,
         conversation=ConversationAccount(),
         recipient=ChannelAccount(),
         from_property=ChannelAccount(),
     )
     return TurnContext(bot_adapter, activity)
Ejemplo n.º 30
0
    async def event_to_activity(event: SlackEvent,
                                client: SlackClient) -> Activity:
        """
        Creates an activity based on the Slack event data.

        :param event: The data of the Slack event.
        :type event: :class:`SlackEvent`
        :param client: The Slack client.
        :type client: :class:`SlackClient`
        :return: An activity containing the event data.
        :rtype: :class:`botbuilder.schema.Activity`
        """

        if not event:
            raise Exception("slack event is required")

        activity = Activity(
            id=event.event_ts,
            channel_id="slack",
            conversation=ConversationAccount(
                id=event.channel if event.channel else event.channel_id,
                properties={}),
            from_property=ChannelAccount(
                id=event.bot_id if event.bot_id else event.user_id if event.
                user_id else event.user),
            recipient=ChannelAccount(id=None),
            channel_data=event,
            text=event.text,
            type=ActivityTypes.event,
            timestamp=datetime.fromtimestamp(float(event.event_ts),
                                             tz=timezone.utc),
        )

        if event.thread_ts:
            activity.conversation.properties["thread_ts"] = event.thread_ts

        if not activity.conversation.id:
            if event.item and event.item_channel:
                activity.conversation.id = event.item_channel
            else:
                activity.conversation.id = event.team

        activity.recipient.id = await client.get_bot_user_by_team(
            activity=activity)

        # If this is a message originating from a user, we'll mark it as such
        # If this is a message from a bot (bot_id != None), we want to ignore it by
        # leaving the activity type as Event.  This will stop it from being included in dialogs,
        # but still allow the Bot to act on it if it chooses (via ActivityHandler.on_event_activity).
        # NOTE: This catches a message from ANY bot, including this bot.
        # Note also, bot_id here is not the same as bot_user_id so we can't (yet) identify messages
        # originating from this bot without doing an additional API call.
        if event.type == "message" and not event.subtype and not event.bot_id:
            activity.type = ActivityTypes.message

        return activity