Esempio n. 1
0
    def append_choices(self, prompt: Activity, channel_id: str,
                       choices: object, style: object,
                       options: object) -> Activity:
        # Get base prompt text (if any)
        text = prompt.text if prompt != None and not prompt.text == False else ''

        # Create temporary msg
        # TODO: fix once ChoiceFactory complete
        def inline() -> Activity:
            # return ChoiceFactory.inline(choices, text, null, options)
            return None

        def list() -> Activity:
            # return ChoiceFactory.list(choices, text, null, options)
            return None

        def suggested_action() -> Activity:
            # return ChoiceFactory.suggested_action(choices, text)
            return None

        def hero_card() -> Activity:
            # return ChoiceFactory.hero_card(choices, text)
            return None

        def list_style_none() -> Activity:
            activity = Activity()
            activity.text = text
            return activity

        def default() -> Activity:
            # return ChoiceFactory.for_channel(channel_id, choices, text, None, options);
            return None

        switcher = {
            # ListStyle.inline
            1: inline,
            2: list,
            3: suggested_action,
            4: hero_card,
            5: list_style_none
        }

        msg = switcher.get(style, default)()

        # Update prompt with text, actions and attachments
        if not prompt:
            # clone the prompt the set in the options (note ActivityEx has Properties so this is the safest mechanism)
            prompt = copy.copy(prompt)

            prompt.text = msg.text

            if (msg.suggested_actions != None
                    and msg.suggested_actions.actions != None
                    and len(msg.suggested_actions.actions) > 0):
                prompt.suggested_actions = msg.suggested_actions

            if msg.attachments != None and len(msg.attachments) > 0:
                prompt.attachments = msg.attachments

            return prompt
        else:
            # TODO: Update to InputHints.ExpectingInput;
            msg.input_hint = None
            return msg
Esempio n. 2
0
 def list_style_none() -> Activity:
     activity = Activity()
     activity.text = text
     return activity
 async def _translate_message_activity(self, activity: Activity,
                                       target_locale: str):
     if activity.type == ActivityTypes.message:
         activity.text = await self.translator.translate(
             activity.text, target_locale)
from botbuilder.core import (
    ConversationState,
    MemoryStorage,
    TurnContext,
    NullTelemetryClient,
)
from botbuilder.dialogs import (
    Dialog,
    DialogSet,
    WaterfallDialog,
    DialogTurnResult,
    DialogTurnStatus,
)

BEGIN_MESSAGE = Activity()
BEGIN_MESSAGE.text = "begin"
BEGIN_MESSAGE.type = "message"

MOCK_TELEMETRY = "botbuilder.applicationinsights.ApplicationInsightsTelemetryClient"


class TelemetryWaterfallTests(aiounittest.AsyncTestCase):
    def test_none_telemetry_client(self):
        # arrange
        dialog = WaterfallDialog("myId")
        # act
        dialog.telemetry_client = None
        # assert
        self.assertEqual(type(dialog.telemetry_client), NullTelemetryClient)

    async def test_execute_sequence_waterfall_steps(self):
Esempio n. 5
0
    def append_choices(
        self,
        prompt: Activity,
        channel_id: str,
        choices: List[Choice],
        style: ListStyle,
        options: ChoiceFactoryOptions = None,
    ) -> Activity:
        """
        Composes an output activity containing a set of choices.
        When overridden in a derived class, appends choices to the activity when the user is prompted for input.
        Helper function to compose an output activity containing a set of choices.

        :param prompt: The prompt to append the user's choice to
        :type prompt:
        :param channel_id: Id of the channel the prompt is being sent to
        :type channel_id: str
        :param: choices: List of choices to append
        :type choices:  :class:`List`
        :param: style: Configured style for the list of choices
        :type style:  :class:`ListStyle`
        :param: options: Optional formatting options to use when presenting the choices
        :type style: :class:`ChoiceFactoryOptions`
        :return: A :class:Task representing the asynchronous operation
        :rtype: :class:Task

        .. note::
            If the task is successful, the result contains the updated activity.
        """
        # Get base prompt text (if any)
        text = prompt.text if prompt is not None and prompt.text else ""

        # Create temporary msg
        # TODO: fix once ChoiceFactory complete
        def inline() -> Activity:
            return ChoiceFactory.inline(choices, text, None, options)

        def list_style() -> Activity:
            return ChoiceFactory.list_style(choices, text, None, options)

        def suggested_action() -> Activity:
            return ChoiceFactory.suggested_action(choices, text)

        def hero_card() -> Activity:
            return ChoiceFactory.hero_card(choices, text)

        def list_style_none() -> Activity:
            activity = Activity(type=ActivityTypes.message)
            activity.text = text
            return activity

        def default() -> Activity:
            return ChoiceFactory.for_channel(channel_id, choices, text, None,
                                             options)

        # Maps to values in ListStyle Enum
        switcher = {
            0: list_style_none,
            1: default,
            2: inline,
            3: list_style,
            4: suggested_action,
            5: hero_card,
        }

        msg = switcher.get(int(style.value), default)()

        # Update prompt with text, actions and attachments
        if prompt:
            # clone the prompt the set in the options (note ActivityEx has Properties so this is the safest mechanism)
            prompt = copy.copy(prompt)

            prompt.text = msg.text

            if (msg.suggested_actions is not None
                    and msg.suggested_actions.actions is not None
                    and msg.suggested_actions.actions):
                prompt.suggested_actions = msg.suggested_actions

            if msg.attachments:
                if prompt.attachments:
                    prompt.attachments.extend(msg.attachments)
                else:
                    prompt.attachments = msg.attachments

            return prompt

        # TODO: Update to InputHints.ExpectingInput;
        msg.input_hint = None
        return msg
Esempio n. 6
0
 def list_style_none() -> Activity:
     activity = Activity(type=ActivityTypes.message)
     activity.text = text
     return activity
Esempio n. 7
0
    def append_choices(
        self,
        prompt: Activity,
        channel_id: str,
        choices: List[Choice],
        style: ListStyle,
        options: ChoiceFactoryOptions = None,
    ) -> Activity:
        """
        Helper function to compose an output activity containing a set of choices.

        Parameters:
        -----------
        prompt: The prompt to append the user's choice to.

        channel_id: ID of the channel the prompt is being sent to.

        choices: List of choices to append.

        style: Configured style for the list of choices.

        options: (Optional) options to configure the underlying `ChoiceFactory` call.
        """
        # Get base prompt text (if any)
        text = prompt.text if prompt is not None and prompt.text else ""

        # Create temporary msg
        # TODO: fix once ChoiceFactory complete
        def inline() -> Activity:
            return ChoiceFactory.inline(choices, text, None, options)

        def list_style() -> Activity:
            return ChoiceFactory.list_style(choices, text, None, options)

        def suggested_action() -> Activity:
            return ChoiceFactory.suggested_action(choices, text)

        def hero_card() -> Activity:
            return ChoiceFactory.hero_card(choices, text)

        def list_style_none() -> Activity:
            activity = Activity(type=ActivityTypes.message)
            activity.text = text
            return activity

        def default() -> Activity:
            return ChoiceFactory.for_channel(channel_id, choices, text, None, options)

        # Maps to values in ListStyle Enum
        switcher = {
            0: list_style_none,
            1: default,
            2: inline,
            3: list_style,
            4: suggested_action,
            5: hero_card,
        }

        msg = switcher.get(int(style.value), default)()

        # Update prompt with text, actions and attachments
        if not prompt:
            # clone the prompt the set in the options (note ActivityEx has Properties so this is the safest mechanism)
            prompt = copy.copy(prompt)

            prompt.text = msg.text

            if (
                msg.suggested_actions is not None
                and msg.suggested_actions.actions is not None
                and msg.suggested_actions.actions
            ):
                prompt.suggested_actions = msg.suggested_actions

            if msg.attachments is not None and msg.attachments:
                prompt.attachments = msg.attachments

            return prompt

        # TODO: Update to InputHints.ExpectingInput;
        msg.input_hint = None
        return msg
Esempio n. 8
0
    def append_choices(self,
                       prompt: Activity,
                       channel_id: str,
                       choices: object,
                       style: object,
                       options: object = None) -> Activity:
        """
        Helper function to compose an output activity containing a set of choices.

        Parameters:
        -----------
        
        prompt: The prompt to append the user's choice to.

        channel_id: ID of the channel the prompt is being sent to.

        choices: List of choices to append.

        style: Configured style for the list of choices.

        options: (Optional) options to configure the underlying `ChoiceFactory` call.
        """
        # Get base prompt text (if any)
        text = prompt.text if prompt != None and not prompt.text == False else ''

        # Create temporary msg
        # TODO: fix once ChoiceFactory complete
        def inline() -> Activity:
            return ChoiceFactory.inline(choices, text, None, options)

        def list_style() -> Activity:
            return ChoiceFactory.list_style(choices, text, None, options)

        def suggested_action() -> Activity:
            return ChoiceFactory.suggested_action(choices, text)

        def hero_card() -> Activity:
            return ChoiceFactory.hero_card(choices, text)

        def list_style_none() -> Activity:
            activity = Activity()
            activity.text = text
            return activity

        def default() -> Activity:
            return ChoiceFactory.for_channel(channel_id, choices, text, None,
                                             options)

        switcher = {
            # ListStyle.inline
            1: inline,
            2: list_style,
            3: suggested_action,
            4: hero_card,
            5: list_style_none
        }

        msg = switcher.get(style, default)()

        # Update prompt with text, actions and attachments
        if not prompt:
            # clone the prompt the set in the options (note ActivityEx has Properties so this is the safest mechanism)
            prompt = copy.copy(prompt)

            prompt.text = msg.text

            if (msg.suggested_actions != None
                    and msg.suggested_actions.actions != None
                    and len(msg.suggested_actions.actions) > 0):
                prompt.suggested_actions = msg.suggested_actions

            if msg.attachments != None and len(msg.attachments) > 0:
                prompt.attachments = msg.attachments

            return prompt
        else:
            # TODO: Update to InputHints.ExpectingInput;
            msg.input_hint = None
            return msg
Esempio n. 9
0
                step_context: WaterfallStepContext) -> DialogTurnResult:
            await step_context.context.send_activity("step2")
            return Dialog.end_of_turn

        async def Waterfall2_Step3(
                step_context: WaterfallStepContext) -> DialogTurnResult:
            await step_context.context.send_activity("step3")
            return Dialog.end_of_turn

        self.add_step(Waterfall2_Step1)
        self.add_step(Waterfall2_Step2)
        self.add_step(Waterfall2_Step3)


begin_message = Activity()
begin_message.text = 'begin'
begin_message.type = 'message'


class WaterfallTests(aiounittest.AsyncTestCase):
    def test_waterfall_none_name(self):
        self.assertRaises(TypeError, (lambda: WaterfallDialog(None)))

    def test_watterfall_add_none_step(self):
        waterfall = WaterfallDialog("test")
        self.assertRaises(TypeError, (lambda: waterfall.add_step(None)))

    async def test_waterfall_with_set_instead_of_array(self):
        self.assertRaises(TypeError, lambda: WaterfallDialog('a', {1, 2}))

    # TODO:WORK IN PROGRESS
Esempio n. 10
0
 async def _translate_message_activity(self, activity: Activity, lang: str):
     if activity.type == ActivityTypes.message:
         activity.text = await self.translator.translate(
             activity.text, lang
         )
Esempio n. 11
0
    async def _fill_out_user_profile(self, flow: ConversationFlow,
                                     profile: UserProfile,
                                     turn_context: TurnContext):
        # Begins flow process
        user_input = turn_context.activity.text.strip()

        # Ask for date; starts conversation flow
        if flow.last_question_asked == Question.NONE:
            await turn_context.send_activity(
                MessageFactory.text(
                    "Let's get started. What date and time would you like to book your movie for?"
                ))
            flow.last_question_asked = Question.DATE

        # Validate date; ask for movie selection
        elif flow.last_question_asked == Question.DATE:
            # This is where date must be bound to profile.date
            validate_result = self._validate_date(user_input)
            if not validate_result.is_valid:
                await turn_context.send_activity(
                    MessageFactory.text(validate_result.message))
            else:
                profile.date = validate_result.value
                await turn_context.send_activity(
                    MessageFactory.text(
                        f"Great! We have a good selection of movies showing at {profile.date}"
                    ))

                await turn_context.send_activity(
                    MessageFactory.text(
                        "Which movie would you like to watch? Please type the name of the movie as your reply."
                    ))
                # movies attachment
                message = Activity(type=ActivityTypes.message)
                message.text = "Moana, Once Upon a Time in Hollywood, Ready Player One, Sicario, The Girl With the Dragon Tattoo."
                message.attachments = [self._get_inline_attachment()]

                await turn_context.send_activity(message)
                flow.last_question_asked = Question.MOVIE

        # Validate movie; ask for seat reservations
        elif flow.last_question_asked == Question.MOVIE:
            ## This is where movie must be bound to profile.movie
            validate_result = self._validate_movie(user_input)
            if not validate_result.is_valid:
                await turn_context.send_activity(
                    MessageFactory.text(validate_result.message))
            else:
                profile.movie = validate_result.value
                await turn_context.send_activity(
                    MessageFactory.text(
                        f"Sounds good! {profile.movie} is a great pick!"))
                await turn_context.send_activity(
                    MessageFactory.text("How many seats are you reserving?"))
                flow.last_question_asked = Question.SEATS

        # Validate seats; ask about row preferences

        elif flow.last_question_asked == Question.SEATS:
            validate_result = self._validate_seats(user_input)
            if not validate_result.is_valid:
                await turn_context.send_activity(
                    MessageFactory.text(validate_result.message))
            else:
                profile.seats = validate_result.value
                await turn_context.send_activity(
                    MessageFactory.text(
                        f"You are booking {profile.seats} seats."))
                await turn_context.send_activity(
                    MessageFactory.text(
                        "What is your row preference? There are 50 rows in our theater."
                    ))
                flow.last_question_asked = Question.PREFERENCE

        # Validate preferences; ask about email

        elif flow.last_question_asked == Question.PREFERENCE:
            validate_result = self._validate_preference(user_input)
            if not validate_result.is_valid:
                await turn_context.send_activity(
                    MessageFactory.text(validate_result.message))
            else:
                profile.preference = validate_result.value
                await turn_context.send_activity(
                    MessageFactory.text(
                        f"Your row preference has been set as {profile.preference}"
                    ))
                await turn_context.send_activity(
                    MessageFactory.text(
                        "Please enter your email for booking confirmation."))
                flow.last_question_asked = Question.EMAIL

        # Validate email, confirm by displaying all info, wrap up w/ NONE
        elif flow.last_question_asked == Question.EMAIL:
            validate_result = self._validate_email(user_input)
            if not validate_result.is_valid:
                await turn_context.send_activity(
                    MessageFactory.text(validate_result.message))
            else:
                profile.email = validate_result.value
                await turn_context.send_activity(
                    MessageFactory.text(
                        f"You have now completed the booking process."))
                await turn_context.send_activity(
                    MessageFactory.text(
                        f"Booking for {profile.email}: {profile.movie} on {profile.date}"
                    ))
                await turn_context.send_activity(
                    MessageFactory.text(
                        f"You are reserving {profile.seats} seats in row {profile.preference}"
                    ))
                await turn_context.send_activity(
                    MessageFactory.text("Type anything to run the bot again."))
                flow.last_question_asked = Question.NONE  #End of flow, able to restart again