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
 def test_conversations_create_conversation(self):
     test_object = ChannelAccount(id=RECIPIENT_ID)
     create_conversation = ConversationParameters(
         bot=ChannelAccount(id=BOT_ID),
         members=[test_object],
         activity=Activity(
             type=ActivityTypes.message,
             channel_id=CHANNEL_ID,
             from_property=ChannelAccount(id=BOT_ID),
             recipient=test_object,
             text="Hi there!",
         ),
     )
     # creds = MicrosoftTokenAuthenticationStub(get_auth_token())
     print("Printing the pointer to the generated MicrosoftAppCredentials:")
     # print(creds)
     connector = ConnectorClient(self.credentials, base_url=SERVICE_URL)
     try:
         conversation = self.loop.run_until_complete(
             connector.conversations.create_conversation(
                 create_conversation))
     except Exception as error:
         raise error
     else:
         assert conversation.id is not None
Esempio n. 3
0
    async def send(self, message: Message):
        """Send a message."""
        if isinstance(message.target, str):
            teams_channel_id = self.parse_channel_id(message.target)
            try:
                connector_client = await self.adapter.create_connector_client(
                    self.service_endpoints[teams_channel_id])
                await connector_client.conversations.create_conversation(
                    ConversationParameters(
                        is_group=True,
                        channel_data={"channel": {
                            "id": teams_channel_id
                        }},
                        activity=MessageFactory.text(message.text),
                    ))
            except KeyError:
                _LOGGER.error(
                    "Unable to send a message until someone has spoken to the bot first."
                )

        elif isinstance(message.target, ConversationReference):
            await self.adapter.continue_conversation(
                message.target,
                lambda turn_context: turn_context.send_activity(message.text),
                self.app_id,
            )

        else:
            _LOGGER.error(
                f"'{message.target}' is not a valid place to send a message.")
Esempio n. 4
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
Esempio n. 5
0
async def send_execsum(req: Request) -> Response:
    try:
        credentials = MicrosoftAppCredentials(CONFIG.APP_ID, CONFIG.APP_PASSWORD)
        client = ConnectorClient(credentials, 'https://smba.trafficmanager.net/fr/')
        teams_client = TeamsConnectorClient(credentials, 'https://smba.trafficmanager.net/fr/')
        teams_channels = teams_client.teams.get_teams_channels('19:[email protected]')
        general_channel = next(channel for channel in teams_channels.conversations if channel.name is None)
        conversation_parameters = ConversationParameters(
            is_group=True,
            channel_data={"channel": {"id": general_channel.id}},
            activity=MessageFactory.attachment(
                CardFactory.adaptive_card({
                    "type": "AdaptiveCard",
                    "version": "1.0",
                    "body": [
                        {
                            "type": "TextBlock",
                            "text": "[email protected] sent an execsum",
                        },
                    ],
                    "actions": [
                        {
                            "type": "Action.OpenUrl",
                            "title": "View execsum",
                            "url": "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf"
                        }
                    ]
                })
            ),
        )
        client.conversations.create_conversation(conversation_parameters)
        return Response(status=HTTPStatus.OK)
    except Exception:
        traceback.print_exc()
    async def _send_proactive_non_threaded_message(self,
                                                   turn_context: TurnContext):
        conversation_reference = TurnContext.get_conversation_reference(
            turn_context.activity)

        conversation_parameters = ConversationParameters(
            is_group=False,
            bot=turn_context.activity.recipient,
            members=[turn_context.activity.from_property],
            tenant_id=turn_context.activity.conversation.tenant_id,
        )
        proactive_message = MessageFactory.text("This is a proactive message")
        proactive_message.label = turn_context.activity.id

        async def get_ref(tc1):
            conversation_reference_inner = TurnContext.get_conversation_reference(
                tc1.activity)
            return await tc1.adapter.continue_conversation(
                conversation_reference_inner, send_message, self._app_id)

        async def send_message(tc2: TurnContext):
            return await tc2.send_activity(proactive_message)

        await turn_context.adapter.create_conversation(
            conversation_reference, get_ref, conversation_parameters)
async def send_private_message(turn_context: TurnContext, user_id: str, activity: Activity):
    """ Send proactive message to the user (Does not broke the chat conversation) """
    conversation_reference = TurnContext.get_conversation_reference(
        turn_context.activity
    )

    conversation_parameters = ConversationParameters(
        is_group=False,
        bot=turn_context.activity.recipient,
        members=[await TeamsInfo.get_member(turn_context, user_id)],
        tenant_id=turn_context.activity.conversation.tenant_id,
    )

    async def get_reference(temp_turn_context_1: TurnContext):
        conversation_reference_inner = TurnContext.get_conversation_reference(
            temp_turn_context_1.activity
        )
        return await temp_turn_context_1.adapter.continue_conversation(
            conversation_reference_inner, send_message, temp_turn_context_1.adapter.settings.app_id
        )

    async def send_message(temp_turn_context_2: TurnContext):
        return await temp_turn_context_2.send_activity(activity)

    await turn_context.adapter.create_conversation(
        conversation_reference, get_reference, conversation_parameters
    )
    async def _message_all_members(self, turn_context: TurnContext):
        team_members = await TeamsInfo.get_members(turn_context)

        for member in team_members:
            conversation_reference = TurnContext.get_conversation_reference(
                turn_context.activity)

            conversation_parameters = ConversationParameters(
                is_group=False,
                bot=turn_context.activity.recipient,
                members=[member],
                tenant_id=turn_context.activity.conversation.tenant_id,
            )

            async def get_ref(tc1):
                conversation_reference_inner = TurnContext.get_conversation_reference(
                    tc1.activity)
                return await tc1.adapter.continue_conversation(
                    conversation_reference_inner, send_message, self._app_id)

            async def send_message(tc2: TurnContext):
                return await tc2.send_activity(
                    f"Hello {member.name}. I'm a Teams conversation bot.")  # pylint: disable=cell-var-from-loop

            await turn_context.adapter.create_conversation(
                conversation_reference, get_ref, conversation_parameters)

        await turn_context.send_activity(
            MessageFactory.text("All messages have been sent"))
    def test_conversations_create_conversation_with_bot_as_only_member_fails(
            self):
        test_object = ChannelAccount(id=BOT_ID)
        sender = ChannelAccount(id=BOT_ID)
        create_conversation = ConversationParameters(
            bot=sender,
            members=[test_object],
            activity=Activity(
                type=ActivityTypes.message,
                channel_id=CHANNEL_ID,
                from_property=sender,
                recipient=test_object,
                text="Hi there!",
            ),
        )

        with pytest.raises(ErrorResponseException) as excinfo:
            connector = ConnectorClient(self.credentials, base_url=SERVICE_URL)
            self.loop.run_until_complete(
                connector.conversations.create_conversation(
                    create_conversation))

        assert excinfo.value.error.error.code == "BadArgument"
        assert "Bots cannot IM other bots" in str(
            excinfo.value.error.error.message)
    async def test_on_create_conversation(self):
        mock_adapter = Mock()

        sut = self.create_skill_handler_for_testing(mock_adapter)
        conversation_parameters = ConversationParameters()

        with self.assertRaises(BotActionNotImplementedError):
            await sut.test_on_create_conversation(self._claims_identity,
                                                  conversation_parameters)
Esempio n. 11
0
async def send_message(req: Request) -> Response:
    try:
        credentials = MicrosoftAppCredentials(CONFIG.APP_ID, CONFIG.APP_PASSWORD)
        client = ConnectorClient(credentials, 'https://smba.trafficmanager.net/fr/')
        teams_client = TeamsConnectorClient(credentials, 'https://smba.trafficmanager.net/fr/')
        teams_channels = teams_client.teams.get_teams_channels('19:[email protected]')
        general_channel = next(channel for channel in teams_channels.conversations if channel.name is None)
        conversation_parameters = ConversationParameters(
            is_group=True,
            channel_data={"channel": {"id": general_channel.id}},
            activity=MessageFactory.content_url('https://picsum.photos/200/300', 'image/png'),
        )
        client.conversations.create_conversation(conversation_parameters)
        return Response(status=HTTPStatus.OK)
    except Exception:
        traceback.print_exc()
    def test_conversations_create_conversation_without_members_fails(self):
        create_conversation = ConversationParameters(
            bot=ChannelAccount(id=BOT_ID),
            activity=Activity(
                type=ActivityTypes.message,
                channel_id=CHANNEL_ID,
                from_property=ChannelAccount(id=BOT_ID),
                text="Hi there!",
            ),
            members=[],
        )

        with pytest.raises(ErrorResponseException) as excinfo:
            connector = ConnectorClient(self.credentials, base_url=SERVICE_URL)
            connector.conversations.create_conversation(create_conversation)

        assert excinfo.value.error.error.code == "BadArgument"
        assert "Conversations" in str(excinfo.value.error.error.message)
    def test_conversations_create_conversation(self):
        test_object = ChannelAccount(id=RECIPIENT_ID)
        create_conversation = ConversationParameters(
            bot=ChannelAccount(id=BOT_ID),
            members=[test_object],
            activity=Activity(
                type=ActivityTypes.message,
                channel_id=CHANNEL_ID,
                from_property=ChannelAccount(id=BOT_ID),
                recipient=test_object,
                text="Hi there!",
            ),
        )

        connector = ConnectorClient(self.credentials, base_url=SERVICE_URL)
        conversation = connector.conversations.create_conversation(
            create_conversation)

        assert conversation.id is not None
    async def teams_create_conversation(self, turn_context: TurnContext,
                                        teams_channel_id: str, message):
        params = ConversationParameters(
            is_group=True,
            channel_data={"channel": {
                "id": teams_channel_id
            }},
            activity=message)

        connector_client = await turn_context.adapter.create_connector_client(
            turn_context.activity.service_url)
        conversation_resource_response = await connector_client.conversations.create_conversation(
            params)
        conversation_reference = TurnContext.get_conversation_reference(
            turn_context.activity)
        conversation_reference.conversation.id = conversation_resource_response.id
        return [
            conversation_reference, conversation_resource_response.activity_id
        ]
    def test_conversations_create_conversation_with_invalid_bot_id_fails(self):
        test_object = ChannelAccount(id=RECIPIENT_ID)
        create_conversation = ConversationParameters(
            bot=ChannelAccount(id="INVALID"),
            members=[test_object],
            activity=Activity(
                type=ActivityTypes.message,
                channel_id=CHANNEL_ID,
                from_property=ChannelAccount(id="INVALID"),
                recipient=test_object,
                text="Hi there!",
            ),
        )

        with pytest.raises(ErrorResponseException) as excinfo:
            connector = ConnectorClient(self.credentials, base_url=SERVICE_URL)
            connector.conversations.create_conversation(create_conversation)

        assert excinfo.value.error.error.code == "ServiceError"
        assert "Invalid userId" in str(excinfo.value.error.error.message)
Esempio n. 16
0
    async def send_message_to_teams_channel(
            turn_context: TurnContext, activity: Activity,
            teams_channel_id: str) -> Tuple[ConversationReference, str]:
        if not turn_context:
            raise ValueError("The turn_context cannot be None")
        if not activity:
            raise ValueError("The activity cannot be None")
        if not teams_channel_id:
            raise ValueError("The teams_channel_id cannot be None or empty")

        old_ref = TurnContext.get_conversation_reference(turn_context.activity)
        conversation_parameters = ConversationParameters(
            is_group=True,
            channel_data={"channel": {
                "id": teams_channel_id
            }},
            activity=activity,
        )

        result = await turn_context.adapter.create_conversation(
            old_ref, TeamsInfo._create_conversation_callback,
            conversation_parameters)
        return (result[0], result[1])
Esempio n. 17
0
    async def create_conversation(
        self,
        reference: ConversationReference,
        logic: Callable[[TurnContext], Awaitable] = None,
        conversation_parameters: ConversationParameters = None,
        channel_id: str = None,
        service_url: str = None,
        credentials: AppCredentials = None,
    ):
        """
        Starts a new conversation with a user. Used to direct message to a member of a group.

        :param reference: The conversation reference that contains the tenant
        :type reference: :class:`botbuilder.schema.ConversationReference`
        :param logic: The logic to use for the creation of the conversation
        :type logic: :class:`typing.Callable`
        :param conversation_parameters: The information to use to create the conversation
        :type conversation_parameters:
        :param channel_id: The ID for the channel.
        :type channel_id: :class:`typing.str`
        :param service_url: The channel's service URL endpoint.
        :type service_url: :class:`typing.str`
        :param credentials: The application credentials for the bot.
        :type credentials: :class:`botframework.connector.auth.AppCredentials`

        :raises: It raises a generic exception error.

        :return: A task representing the work queued to execute.

        .. remarks::
            To start a conversation, your bot must know its account information and the user's
            account information on that channel.
            Most channels only support initiating a direct message (non-group) conversation.
            The adapter attempts to create a new conversation on the channel, and
            then sends a conversation update activity through its middleware pipeline
            to the the callback method.
            If the conversation is established with the specified users, the ID of the activity
            will contain the ID of the new conversation.
        """
        try:
            if not service_url:
                service_url = reference.service_url
                if not service_url:
                    raise TypeError(
                        "BotFrameworkAdapter.create_conversation(): service_url or reference.service_url is required."
                    )

            if not channel_id:
                channel_id = reference.channel_id
                if not channel_id:
                    raise TypeError(
                        "BotFrameworkAdapter.create_conversation(): channel_id or reference.channel_id is required."
                    )

            parameters = (conversation_parameters if conversation_parameters
                          else ConversationParameters(bot=reference.bot,
                                                      members=[reference.user],
                                                      is_group=False))

            # Mix in the tenant ID if specified. This is required for MS Teams.
            if reference.conversation 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

            # This is different from C# where credentials are required in the method call.
            # Doing this for compatibility.
            app_credentials = (credentials if credentials else await
                               self.__get_app_credentials(
                                   self.settings.app_id,
                                   self.__get_botframework_oauth_scope()))

            # Create conversation
            client = self._get_or_create_connector_client(
                service_url, app_credentials)

            resource_response = await client.conversations.create_conversation(
                parameters)

            event_activity = Activity(
                type=ActivityTypes.event,
                name="CreateConversation",
                channel_id=channel_id,
                service_url=service_url,
                id=resource_response.activity_id
                if resource_response.activity_id else str(uuid.uuid4()),
                conversation=ConversationAccount(
                    id=resource_response.id,
                    tenant_id=parameters.tenant_id,
                ),
                channel_data=parameters.channel_data,
                recipient=parameters.bot,
            )

            context = self._create_context(event_activity)
            context.turn_state[BotAdapter.BOT_CONNECTOR_CLIENT_KEY] = client

            claims_identity = ClaimsIdentity(
                claims={
                    AuthenticationConstants.AUDIENCE_CLAIM:
                    app_credentials.microsoft_app_id,
                    AuthenticationConstants.APP_ID_CLAIM:
                    app_credentials.microsoft_app_id,
                    AuthenticationConstants.SERVICE_URL_CLAIM: service_url,
                },
                is_authenticated=True,
            )
            context.turn_state[BotAdapter.BOT_IDENTITY_KEY] = claims_identity

            return await self.run_pipeline(context, logic)

        except Exception as error:
            raise error
    async def create_conversation(
        self,
        reference: ConversationReference,
        logic: Callable[[TurnContext], Awaitable] = None,
        conversation_parameters: ConversationParameters = None,
    ):
        """
        Starts a new conversation with a user. Used to direct message to a member of a group.

        :param reference: The conversation reference that contains the tenant
        :type reference: :class:`botbuilder.schema.ConversationReference`
        :param logic: The logic to use for the creation of the conversation
        :type logic: :class:`typing.Callable`
        :param conversation_parameters: The information to use to create the conversation
        :type conversation_parameters:

        :raises: It raises a generic exception error.

        :return: A task representing the work queued to execute.

        .. remarks::
            To start a conversation, your bot must know its account information and the user's
            account information on that channel.
            Most channels only support initiating a direct message (non-group) conversation.
            The adapter attempts to create a new conversation on the channel, and
            then sends a conversation update activity through its middleware pipeline
            to the the callback method.
            If the conversation is established with the specified users, the ID of the activity
            will contain the ID of the new conversation.</para>
        """
        try:
            if reference.service_url is None:
                raise TypeError(
                    "BotFrameworkAdapter.create_conversation(): reference.service_url cannot be None."
                )

            # Create conversation
            parameters = (conversation_parameters if conversation_parameters
                          else ConversationParameters(bot=reference.bot,
                                                      members=[reference.user],
                                                      is_group=False))
            client = await 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(type=ActivityTypes.event, name="CreateConversation"),
                reference,
                is_incoming=True,
            )
            request.conversation = ConversationAccount(
                id=resource_response.id, tenant_id=parameters.tenant_id)
            request.channel_data = parameters.channel_data
            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 error:
            raise error
Esempio n. 19
0
    async def _message_all_members(self, turn_context: TurnContext,
                                   transcription_text, meeting_url, GUID):
        team_members = await self._get_paged_members(turn_context)

        for member in team_members:
            # check if member's name was mentioned in meeting
            member_first_name = member.name.split(" ")[0]

            if transcription_text.lower().find(
                    member_first_name.lower()) != -1:
                mentioned_members_list.append(member_first_name)

                # split text into words. Remove punctuation to prevent mistakes in indexing
                transcription_text = transcription_text.replace(",", "")
                transcription_text = transcription_text.replace(".", "")
                transcription_text = transcription_text.replace("?", " ")
                transcription_text = transcription_text.replace("\\r", " ")
                transcription_text = transcription_text.replace("\\n", "")

                transcription_list = transcription_text.lower().split(" ")

                mentioned_messages_list = []

                startIndex = -1
                matchFound = 0
                for i in range(0, len(transcription_list)):

                    try:
                        # find name placement in transcription list
                        indexFound = transcription_list.index(
                            member_first_name.lower(), startIndex + 1)
                    except:
                        # if name is no longer in transcription list..break loop of looking for more name mentions
                        break

                    # get range of words around name to get context and form message
                    context_threshold_range = 10
                    context_message = ""

                    # compose message with context
                    for word in range(indexFound - context_threshold_range,
                                      indexFound + context_threshold_range):
                        context_message += transcription_list[word] + " "

                    # add mentioned message instnace into list of mentions (multiple times during a meeting)
                    message_start_time = TranscriptionScraper.getTimeStamps(
                        GUID, member_first_name.lower())
                    context_message += "... @" + message_start_time[
                        matchFound] + "|"
                    matchFound = matchFound + 1
                    mentioned_messages_list.append(context_message)

                    # update startIndex to start after found
                    startIndex = indexFound

                conversation_reference = TurnContext.get_conversation_reference(
                    turn_context.activity)

                conversation_parameters = ConversationParameters(
                    is_group=False,
                    bot=turn_context.activity.recipient,
                    members=[member],
                    tenant_id=turn_context.activity.conversation.tenant_id,
                )

                async def get_ref(tc1):
                    conversation_reference_inner = TurnContext.get_conversation_reference(
                        tc1.activity)
                    return await tc1.adapter.continue_conversation(
                        conversation_reference_inner, send_message,
                        self._app_id)

                buttons = [
                    CardAction(type=ActionTypes.message_back,
                               title="See Meeting Recording",
                               text="recording",
                               value={"meetingURL": meeting_url})
                ]
                mentions_text = ','.join(mentioned_messages_list)

                card = HeroCard(
                    title="Hi you were mentioned in this meeting!",
                    subtitle="See the context of the mentions below!",
                    text=mentions_text,
                    buttons=buttons)

                async def send_message(tc2: TurnContext):
                    return await tc2.send_activity(
                        MessageFactory.attachment(CardFactory.hero_card(card)))  # pylint: disable=cell-var-from-loop

                await turn_context.adapter.create_conversation(
                    conversation_reference, get_ref, conversation_parameters)
        mentioned_members = ','.join(mentioned_members_list)

        await turn_context.send_activity(
            MessageFactory.text(
                "All members who's names were mentioned in the meeting were notified with context: "
                + mentioned_members))
        mentioned_members_list.clear()