def _update_attachment_streams(self, activity: Activity) -> List[object]:
        if not activity or not activity.attachments:
            return None

        def validate_int_list(obj: object) -> bool:
            if not isinstance(obj, list):
                return False

            return all(isinstance(element, int) for element in obj)

        stream_attachments = [
            attachment for attachment in activity.attachments
            if validate_int_list(attachment.content)
        ]

        if stream_attachments:
            activity.attachments = [
                attachment for attachment in activity.attachments
                if not validate_int_list(attachment.content)
            ]

            # TODO: validate StreamContent parallel
            return [
                StreamContent(
                    attachment.content,
                    headers={"Content-Type": attachment.content_type},
                ) for attachment in stream_attachments
            ]

        return None
예제 #2
0
    async def _handle_outgoing_attachment(self, turn_context: TurnContext):
        reply = Activity(type=ActivityTypes.message)

        first_char = turn_context.activity.text[0]
        if first_char == "1":
            reply.text = "This is an inline attachment."
            reply.attachments = [self._get_inline_attachment()]
        elif first_char == "2":
            reply.text = "This is an internet attachment."
            reply.attachments = [self._get_internet_attachment()]
        elif first_char == "3":
            reply.text = "This is an uploaded attachment."
            reply.attachments = [await self._get_upload_attachment(turn_context)]
        else:
            reply.text = "Your input was not recognized, please try again."

        await turn_context.send_activity(reply)
예제 #3
0
 async def _send_welcome_message(self, turn_context: TurnContext):
     """
     Greet the user and give them instructions on how to interact with the bot.
     :param turn_context:
     :return:
     """
     reply = Activity(type=ActivityTypes.message)
     reply.text = "Hello and welcome! \n\n Send photo of the handwrited spiral to get probability of PD"
     reply.attachments = [await self._get_spiral_example(turn_context)]
     await turn_context.send_activity(reply)
예제 #4
0
async def create_reply_activity(request_activity: Activity, text: str, attachment: Attachment = None) -> Activity:
    activity = Activity(
        type=ActivityTypes.message,
        channel_id=request_activity.channel_id,
        conversation=request_activity.conversation,
        recipient=request_activity.from_property,
        from_property=request_activity.recipient,
        text=text,
        service_url=request_activity.service_url)
    if attachment:
        activity.attachments = [attachment]
    return activity
예제 #5
0
    async def func(turn_context: TurnContext):
        reply = Activity(type=ActivityTypes.message)

        if body.image:
            attachment = Attachment(
                name="person.png",
                content_type="image/png",
                content_url=f"data:image/png;base64,{body.image}",
            )
            reply.attachments = [attachment]

        reply.text = '\U0001F3E0 Qualcuno è tornato a casa ma non so chi sia.'

        await turn_context.send_activity(reply)
예제 #6
0
    def append_choices(self, prompt: Activity, channel_id: str, choices: object, style: object, options : object = None ) -> 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, 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
예제 #7
0
 def create_reply_activity(self,
                           request_activity,
                           activity_type,
                           text=None,
                           attachment=None):
     activity = Activity(type=activity_type,
                         channel_id=request_activity.channel_id,
                         conversation=request_activity.conversation,
                         recipient=request_activity.from_property,
                         from_property=request_activity.recipient,
                         service_url=request_activity.service_url)
     if text:
         activity.text = text
     if attachment:
         activity.attachments = [attachment]
     return activity
예제 #8
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.

        :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 task representing the asynchronous operation

        .. remarks::
            If the task is successful, the result contains the updated activity.
            When overridden in a derived class, appends choices to the activity when the user
            is prompted for input. This is an helper function to compose an output activity
            containing a set of choices.

        """
        # 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
예제 #9
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
예제 #10
0
    async def loop_step(self, step_context: WaterfallStepContext):

        country = step_context.values["country"].capitalize()

        # If they chose an option execute script
        if step_context.result.value == 'Covid-19 Cases':

            await step_context.context.send_activity(
                MessageFactory.text("Wait a moment..."))

            querystring = {"country": "{}".format(country)}
            response = requests.request("GET",
                                        url,
                                        headers=headers,
                                        params=querystring)
            response_json = json.loads(response.text)

            new_cases = response_json['response'][0]['cases']['new']
            active_cases = response_json['response'][0]['cases']['active']
            recovered_cases = response_json['response'][0]['cases'][
                'recovered']

            await step_context.context.send_activity(
                MessageFactory.text(f"COVID-19 Cases from {country} \n\n"
                                    f"New Cases {new_cases} \n\n"
                                    f"Active Cases {active_cases} \n\n"
                                    f"Recovered Cases {recovered_cases} \n\n"))

            reply = Activity(type=ActivityTypes.message)
            reply.attachments = [self._get_inline_attachment(country)]
            await step_context.context.send_activity(reply)

        if step_context.result.value == 'Covid-19 Deaths':
            await step_context.context.send_activity(
                MessageFactory.text("Wait a moment..."))

            querystring = {"country": "{}".format(country)}
            response = requests.request("GET",
                                        url,
                                        headers=headers,
                                        params=querystring)
            response_json = json.loads(response.text)

            new_deaths = response_json['response'][0]['deaths']['new']
            m_deaths = response_json['response'][0]['deaths']['1M_pop']
            total_deaths = response_json['response'][0]['deaths']['total']

            await step_context.context.send_activity(
                MessageFactory.text(f"COVID-19 Deaths from {country} \n\n"
                                    f"New Deaths {new_deaths} \n\n"
                                    f"1M_pop Deaths {m_deaths} \n\n"
                                    f"Total Deaths {total_deaths} \n\n"))

        if step_context.result.value == 'Covid-19 Tests':
            await step_context.context.send_activity(
                MessageFactory.text("Wait a moment..."))

            querystring = {"country": "{}".format(country)}
            response = requests.request("GET",
                                        url,
                                        headers=headers,
                                        params=querystring)
            response_json = json.loads(response.text)

            m_tests = response_json['response'][0]['tests']['1M_pop']
            total_tests = response_json['response'][0]['tests']['total']

            await step_context.context.send_activity(
                MessageFactory.text(f"COVID-19 PCR Tests from {country} \n\n"
                                    f"New Tests {m_tests} \n\n"
                                    f"Total PCR Tests {total_tests} \n\n"))

        if step_context.result.value == 'Covid-19 Twitter':

            await step_context.context.send_activity(
                MessageFactory.text(
                    "Obtaining last tweets in your country related to COVID-19 wait a moment..."
                ))

            result = []

            query = f'{country} AND covid OR covid-19 OR coronavirus OR Covid-19'

            for tweet in tweepy.Cursor(api.search, q=query).items(5):
                reply = MessageFactory.list([])
                reply.attachments.append(self.create_tweet_card(tweet))
                await step_context.context.send_activity(reply)

        if step_context.result.value == 'Covid-19 Meme':
            # show covid meme
            reply = MessageFactory.list([])
            reply.attachments.append(self.create_hero_card())
            await step_context.context.send_activity(reply)

        # If they're done, exit and return their list.
        elif step_context.result.value == 'Done':
            return await step_context.end_dialog()

        # Otherwise, repeat this dialog, passing in the selections from this iteration.
        return await step_context.replace_dialog(ReviewSelectionDialog.__name__
                                                 )
예제 #11
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
예제 #12
0
    async def loop_step(self, step_context: WaterfallStepContext):

        country = step_context.values["country"].capitalize()
        
        # If they chose an option execute script
        if step_context.result.value == 'Covid-19 Cases':

            await step_context.context.send_activity(MessageFactory.text("Wait a moment..."))

            querystring = {"country":"{}".format(country)}
            response = requests.request("GET", url, headers=headers, params=querystring)
            response_json = json.loads(response.text)

            new_cases = response_json['response'][0]['cases']['new']
            active_cases = response_json['response'][0]['cases']['active']
            recovered_cases = response_json['response'][0]['cases']['recovered']

            await step_context.context.send_activity(
                MessageFactory.text(
                    f"COVID-19 Cases from {country} \n\n"
                    f"New Cases {new_cases} \n\n"
                    f"Active Cases {active_cases} \n\n"
                    f"Recovered Cases {recovered_cases} \n\n"
                    )
                )   
            
            reply = Activity(type=ActivityTypes.message)
            reply.attachments = [self._get_inline_attachment(country)]
            await step_context.context.send_activity(reply)

        
        if step_context.result.value == 'Covid-19 Deaths':
            await step_context.context.send_activity(MessageFactory.text("Wait a moment..."))

            querystring = {"country":"{}".format(country)}
            response = requests.request("GET", url, headers=headers, params=querystring)
            response_json = json.loads(response.text)

            new_deaths = response_json['response'][0]['deaths']['new']
            m_deaths = response_json['response'][0]['deaths']['1M_pop']
            total_deaths = response_json['response'][0]['deaths']['total']

            await step_context.context.send_activity(
                MessageFactory.text(
                    f"COVID-19 Deaths from {country} \n\n"
                    f"New Deaths {new_deaths} \n\n"
                    f"1M_pop Deaths {m_deaths} \n\n"
                    f"Total Deaths {total_deaths} \n\n"
                    )
                )   
        
        if step_context.result.value == 'Covid-19 Tests':
            await step_context.context.send_activity(MessageFactory.text("Wait a moment..."))

            querystring = {"country":"{}".format(country)}
            response = requests.request("GET", url, headers=headers, params=querystring)
            response_json = json.loads(response.text)

            m_tests = response_json['response'][0]['tests']['1M_pop']
            total_tests = response_json['response'][0]['tests']['total']

            await step_context.context.send_activity(
                MessageFactory.text(
                    f"COVID-19 PCR Tests from {country} \n\n"
                    f"New Tests {m_tests} \n\n"
                    f"Total PCR Tests {total_tests} \n\n"
                    )
                )  

        # If they're done, exit and return their list.
        elif step_context.result.value == 'Done':
            return await step_context.end_dialog()

        # Otherwise, repeat this dialog, passing in the selections from this iteration.
        return await step_context.replace_dialog(StatsSelectionDialog.__name__)
예제 #13
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