async def _mention_activity(self, turn_context: TurnContext):
        mention = Mention(
            mentioned=turn_context.activity.from_property,
            text=f"<at>{turn_context.activity.from_property.name}</at>",
            type="mention",
        )

        reply_activity = MessageFactory.text(f"Hello {mention.text}")
        reply_activity.entities = [Mention().deserialize(mention.serialize())]
        await turn_context.send_activity(reply_activity)
예제 #2
0
    def __send(self, text, conversation, mentions=None):
        logger.info(f"Sending message: {text}")
        entities = list()
        if mentions is None:
            mentions = list()
        for name in mentions:
            user_id = self._user_map.get(name)
            if not user_id:
                logger.info("User not found: %s" % name)
                continue
            mention = Mention(mentioned=ChannelAccount(id=user_id, name=name), text="<at>%s</at>" % name,
                              type="mention")
            entities.append(mention)

        credentials = MicrosoftAppCredentials(self._app_id, self._app_password)
        connector = ConnectorClient(credentials, base_url=self._service_url)

        reply = Activity(
            type=ActivityTypes.message,
            channel_id=self._current_channel,
            conversation=conversation,
            from_property=ChannelAccount(id=self._current_bot_id["id"], name=self._current_bot_id["name"]),
            entities=entities,
            text=text,
            service_url=self._service_url)

        response = connector.conversations.send_to_conversation(reply.conversation.id, reply)
        logger.info(response)
예제 #3
0
    async def on_message_activity(self, turn_context: TurnContext):
        mention_data = {
            "mentioned": turn_context.activity.from_property,
            "text": f"<at>{turn_context.activity.from_property.name}</at>",
            "type": "mention",
        }

        mention_object = Mention(**mention_data)

        reply_activity = MessageFactory.text(f"Hello {mention_object.text}")
        reply_activity.entities = [mention_object]
        await turn_context.send_activity(reply_activity)
예제 #4
0
    def test_should_remove_at_mention_from_activity(self):
        activity = Activity(
            type="message",
            text="<at>TestOAuth619</at> test activity",
            recipient=ChannelAccount(id="TestOAuth619"),
            entities=[
                Mention(
                    type="mention",
                    text="<at>TestOAuth619</at>",
                    mentioned=ChannelAccount(name="Bot", id="TestOAuth619"),
                )
            ],
        )

        text = TurnContext.remove_recipient_mention(activity)

        assert text, " test activity"
        assert activity.text, " test activity"
    def test_should_remove_at_mention_with_regex_characters(self):
        activity = Activity(
            type="message",
            text="<at>Test (*.[]$%#^&?)</at> test activity",
            recipient=ChannelAccount(id="Test (*.[]$%#^&?)"),
            entities=[
                Entity().deserialize(
                    Mention(
                        type="mention",
                        text="<at>Test (*.[]$%#^&?)</at>",
                        mentioned=ChannelAccount(name="Bot",
                                                 id="Test (*.[]$%#^&?)"),
                    ).serialize())
            ],
        )

        text = TurnContext.remove_recipient_mention(activity)

        assert text == " test activity"
        assert activity.text == " test activity"
    async def test_should_replicate_activity_data_to_listening_emulator_following_open_and_attach_with_at_mention(
        self
    ):
        inbound_expectation, outbound_expectation, state_expectation = (
            False,
            False,
            False,
        )

        with requests_mock.Mocker() as mocker:
            # set up our expectations in nock - each corresponds to a trace message we expect to receive in the emulator

            def match_response(request):
                nonlocal inbound_expectation, outbound_expectation, state_expectation
                r_json = loads(request.text)
                if r_json.get("type", None) != "trace":
                    return None

                if r_json.get("value", {}).get("text", None) == "hi":
                    inbound_expectation = True
                    return inbound_expectation
                if r_json.get("value", {}).get("text", None) == "echo: hi":
                    outbound_expectation = True
                    return outbound_expectation

                x_property = (
                    r_json.get("value", {})
                    .get("user_state", {})
                    .get("x", {})
                    .get("property", None)
                )
                y_property = (
                    r_json.get("value", {})
                    .get("conversation_state", {})
                    .get("y", {})
                    .get("property", None)
                )
                state_expectation = x_property == "hello" and y_property == "world"
                return state_expectation

            mocker.post(
                "https://test.com/v3/conversations/Convo1/activities",
                additional_matcher=match_response,
                json={"id": "test"},
                status_code=200,
            )

            # create the various storage and middleware objects we will be using

            storage = MemoryStorage()
            inspection_state = InspectionState(storage)
            user_state = UserState(storage)
            conversation_state = ConversationState(storage)
            inspection_middleware = InspectionMiddleware(
                inspection_state, user_state, conversation_state
            )

            # the emulator sends an /INSPECT open command - we can use another adapter here

            open_activity = MessageFactory.text("/INSPECT open")

            async def exec_test(turn_context):
                await inspection_middleware.process_command(turn_context)

            inspection_adapter = TestAdapter(exec_test, None, True)

            await inspection_adapter.receive_activity(open_activity)

            inspection_open_result_activity = inspection_adapter.activity_buffer[0]

            recipient_id = "bot"
            attach_command = (
                f"<at>{ recipient_id }</at> { inspection_open_result_activity.value }"
            )

            # the logic of teh bot including replying with a message and updating user and conversation state

            x_prop = user_state.create_property("x")
            y_prop = conversation_state.create_property("y")

            async def exec_test2(turn_context):

                await turn_context.send_activity(
                    MessageFactory.text(f"echo: {turn_context.activity.text}")
                )

                (await x_prop.get(turn_context, {"property": ""}))["property"] = "hello"
                (await y_prop.get(turn_context, {"property": ""}))["property"] = "world"

                await user_state.save_changes(turn_context)
                await conversation_state.save_changes(turn_context)

            application_adapter = TestAdapter(exec_test2, None, True)

            # IMPORTANT add the InspectionMiddleware to the adapter that is running our bot

            application_adapter.use(inspection_middleware)

            attach_activity = Activity(
                type=ActivityTypes.message,
                text=attach_command,
                recipient=ChannelAccount(id=recipient_id),
                entities=[
                    Mention(
                        type="mention",
                        text=f"<at>{recipient_id}</at>",
                        mentioned=ChannelAccount(name="Bot", id=recipient_id),
                    )
                ],
            )
            await application_adapter.receive_activity(attach_activity)

            # the attach command response is a informational message

            await application_adapter.receive_activity(MessageFactory.text("hi"))

            # trace activities should be sent to the emulator using the connector and the conversation reference

        # verify that all our expectations have been met
        assert inbound_expectation
        assert outbound_expectation
        assert state_expectation
        assert mocker.call_count, 3
예제 #7
0
    async def on_message_activity(self, turn_context: TurnContext):
        """
        Respond to messages sent from the user.
        """
        self._add_conversation_reference(turn_context.activity)

        global trak_name
        global trak_allergy_url
        global trak_careProvider
        global trak_dob
        global trak_gender
        global trak_recordNumber
        global trak_url
        global gname
        global trak_lastUpdated
        global allergy_data
        global OAuth_url
        global r_name
        global r_urn
        global r_url
        global ob_url
        global r_sender
        global r_message

        # Get the state properties from the turn context.
        welcome_user_state = await self.user_state_accessor.get(
            turn_context, WelcomeUserState)

        if not welcome_user_state.did_welcome_user:
            welcome_user_state.did_welcome_user = True

            # Will be on first message from user
            await turn_context.send_activity("Welcome Back !")

            name = turn_context.activity.from_property.name
            gname = name
            await turn_context.send_activity(
                f"What can I help you with {name} ?")

        else:
            # removes mention from the user input in channels or group
            TurnContext.remove_recipient_mention(turn_context.activity)

            # Credentials for OAuth2
            authorize_url = "https://tcfhirsandbox.intersystems.com.au/oauth2/authorize"
            token_url = "https://tcfhirsandbox.intersystems.com.au/oauth2/token"
            state = 'asdasdasdasdasdasasd'
            scope = 'patient%2F*.read%20launch%2Fpatient'
            callback_uri = "x-argonaut-app://HealthProviderLogin/"
            my_redirect = "https://23deef16c21f.ngrok.io/api/auth_code"
            test_redirect = "https://www.intersystems.com"
            client_id = '6A605kYem9GmG38Vo6TTzh8IFnjWHZWtRn46K1hoxQY'
            r_client_id = "2rv9NDv0WFZVS19o3VTZbrMjqX8mjiCFrxab7dknSC0"
            client_secret = 'POrisHrcdMvUKmaR6Cea0b8jtx-z4ewVWrnaIXASO-H3tB3g5MgPV7Vqty7OP8aEbSGENWRMkeVuJJKZDdG7Pw'
            new_secret = "UcU7Kzo-6oYRfuCfcL0wUgsiEXQIT2kQOfCqir6wFRdSXjML1y80bJp29_4Q9GqYRXI-5vIswB1KVGIhIiNXjg"
            #OAuth_url = authorize_url + '?response_type=code&state=' + state + '&client_id=' + r_client_id + '&scope='+scope+'&redirect_uri=' + callback_uri
            OAuth_url = authorize_url + '?response_type=code&state=' + state + '&client_id=' + client_id + '&scope=' + scope + '&redirect_uri=' + callback_uri
            # Process data from teams to check if there is input via cards
            channelData = turn_context.activity.channel_data
            enter_val = turn_context.activity.value
            if enter_val != None or "postBack" in channelData:
                global token
                try:
                    val = json.dumps(turn_context.activity.value)
                    commandToken = json.loads(val)
                    authorization_code = commandToken['SimpleVal']
                    data = {
                        'grant_type': 'authorization_code',
                        'code': authorization_code,
                        'redirect_uri': callback_uri
                    }
                    access_token_response = requests.post(token_url,
                                                          data=data,
                                                          verify=True,
                                                          allow_redirects=True,
                                                          auth=(client_id,
                                                                client_secret))
                    tokens = json.loads(access_token_response.text)
                    access_token = tokens['access_token']
                    token = access_token
                    await turn_context.send_activity(f"Login successful !​​​​")
                    return None
                except:
                    await turn_context.send_activity(
                        f"Authorization Code is Invalid !")

            # makes the text in lower case and strips of any spaces
            text = turn_context.activity.text.lower().strip()
            # splits the user input and makes a list
            ltxt = text.split(" ")

            # Use this if cards dosen't work for you, token needs to be entered manually each time it expires.
            #token = 'IiU-3EAUcBTssUvwh7FcQuM1buLNhAq-Y52r_Bkiemo90m5LG6yx0R-XpWRPwX9bMPdJS4Vt1ynhBMAmsK_k0w'

            # header for reqesting data from FHIR
            call_header = {
                'accept': 'application/json',
                'Authorization': 'Bearer ' + token
            }

            # keywords that will be used by the bot to compare the user input and react accordingly
            if text in ("hello", "hi"):
                await turn_context.send_activity(
                    f"why would you say {text} again ?")

            elif text in ("help", "intro"):
                await self.__send_intro_card(turn_context)

            elif text in ("login"):
                await self.__send_oauth_card(turn_context)

            elif text == "delete":
                self.list_care_provider.clear()
                await turn_context.send_activity(
                    "The care provider list is empty now!")

            elif text == "standard channel":
                if turn_context.activity.channel_id == Channels.ms_teams:
                    try:
                        graph_token = get_graph_token()
                        standard_channel(graph_token)
                        await turn_context.send_activity(
                            "A standard channel created!")
                    except:
                        await turn_context.send_activity(
                            "This function is only supported in teams/channels!"
                        )

                else:
                    await turn_context.send_activity(
                        "This function is only supported in Microsoft Teams")

            elif text == "private channel":
                if turn_context.activity.channel_id == Channels.ms_teams:
                    try:
                        graph_token = get_graph_token()
                        members = all_team_members(graph_token)["value"]
                        ids = []
                        for provider in self.list_care_provider:
                            for member in members:
                                if member["displayName"] == provider['name']:
                                    ids.append(member["id"])
                        ls_member = []
                        count = 0
                        for id_number in ids:
                            if count == 0:
                                add = owner_object(id_number)
                            else:
                                add = member_object(id_number)
                            ls_member.append(add)
                            count = count + 1
                        if len(ls_member) == 0:
                            await turn_context.send_activity(
                                "No provider is received")
                        else:
                            private_channel(graph_token, ls_member)
                            await turn_context.send_activity(
                                "A private channel with the care providers created!"
                            )

                    except:
                        await turn_context.send_activity(
                            "This function is only supported in teams/channels!"
                        )

                else:
                    await turn_context.send_activity(
                        "This function is only supported in Microsoft Teams")

            elif text in ("patient"):
                await turn_context.send_activity(
                    'Please type the patient ID after patient. Eg: "patient 137"'
                )

            elif ltxt[0] == "patient":
                if ltxt[1] != "0":
                    url = "https://tcfhirsandbox.intersystems.com.au/fhir/dstu2/Patient/" + ltxt[
                        1]
                    response = requests.get(url,
                                            headers=call_header,
                                            verify=True)

                    if response.status_code == 404:
                        await turn_context.send_activity("Patient not found !")
                    elif response.status_code == 401:
                        await turn_context.send_activity(
                            "Your token has expired !")
                    elif response.status_code == 200:
                        r_dict = json.loads(response.text)

                        trak_url = (
                            f"https://tcfhirsandbox.intersystems.com.au/t2019grxx/csp/system.Home.cls#/Direct/AW.Direct.EPR?RegistrationNo={str(r_dict['identifier'][1]['value'])}"
                        )
                        ob_url = "https://www.google.com/"

                        try:
                            pat_name = (f"{r_dict['name'][0]['text']}")
                            trak_name = pat_name.upper()
                        except:
                            trak_name = "Couldn't find NAME in database"
                        try:
                            lastUpdated = (f"{r_dict['meta']['lastUpdated']}")
                            utc = (f"{lastUpdated[0:10]} {lastUpdated[12:19]}")
                            trak_lastUpdated = zone_convertor(utc)
                        except:
                            trak_lastUpdated = "No DATE found"
                        try:
                            trak_careProvider = (
                                f"{r_dict['careProvider'][0]['display']}")
                        except:
                            trak_careProvider = "Couldn't find CARE PROVIDER in database"
                        try:
                            trak_recordNumber = (
                                f"{r_dict['identifier'][1]['value']}")
                        except:
                            trak_recordNumber = "Couldn't find RECORD NUMBER in database"
                        try:
                            trak_dob = (f"{r_dict['birthDate']}")
                        except:
                            trak_dob = "Couldn't find DOB in database"
                        try:
                            trak_gender = (f"{r_dict['gender']}")
                        except:
                            trak_gender = "GENDER is not disclosed by the patient"

                        trak_allergy_url = (
                            f"https://tcfhirsandbox.intersystems.com.au/fhir/dstu2/Patient/{ltxt[1]}/AllergyIntolerance"
                        )

                        allergy_resposne = requests.get(trak_allergy_url,
                                                        headers=call_header,
                                                        verify=True)
                        a_dict = json.loads(allergy_resposne.text)
                        a_total = (f"{a_dict['total']}")

                        if a_total != "0":
                            count = int(a_total)
                            index = count - 1
                            allergy_name = ""
                            allergy_reaction = ""
                            allergy_severity = ""
                            allergy_recordedDate = ""

                            while count != 0:
                                try:
                                    allergy_name = allergy_name + (
                                        f"{a_dict['entry'][index]['resource']['substance']['text']}:"
                                    )
                                except:
                                    allergy_name = "Unknown"
                                try:
                                    allergy_reaction = allergy_reaction + (
                                        f"{a_dict['entry'][index]['resource']['reaction'][0]['manifestation'][0]['text']}:"
                                    )  # it is possible that there are more sublist under reaction and manifestation
                                except:
                                    allergy_reaction = "No record found"
                                try:
                                    allergy_severity = allergy_severity = allergy_severity + (
                                        f"{a_dict['entry'][index]['resource']['reaction'][0]['severity']}:"
                                    )
                                except:
                                    allergy_severity = "No record found"
                                try:
                                    utc_date = (
                                        f"{a_dict['entry'][index]['resource']['recordedDate']}|"
                                    )
                                    dt = utc_date.split("T")
                                    t = dt[1].split("+")
                                    dt_format = (f"{dt[0]} {t[0]}")
                                    allergy_recordedDate = allergy_recordedDate + zone_convertor(
                                        dt_format) + "|"
                                except:
                                    allergy_recordedDate = "Date Unknown"

                                index = index - 1
                                count = count - 1

                            list_name = allergy_name.split(":")
                            list_reaction = allergy_reaction.split(":")
                            list_severity = allergy_severity.split(":")
                            list_date = allergy_recordedDate.split("|")

                            allergy_data = ""
                            total_allergy = int(a_total)

                            list_index = 0
                            while list_index < total_allergy:
                                allergy_data = allergy_data + (
                                    f"Allergen : {list_name[list_index]}\n\nReaction : {list_reaction[list_index]}\n\nSeverity : {list_severity[list_index]}\n\nRecorded Date : {list_date[list_index]}\n\n-------------------------------------\n\n"
                                )
                                list_index += 1
                        else:
                            allergy_data = (
                                f"{trak_name} have no recorded allergies")

                        await self.__send_about_card(turn_context)

                    else:
                        await turn_context.send_activity(
                            "You are not logged in. Please type 'Login' to start your session !"
                        )

            elif ltxt[0] == "mrn":

                url = "https://tcfhirsandbox.intersystems.com.au/fhir/dstu2/Patient?identifier=" + ltxt[
                    1]
                response = requests.get(url, headers=call_header, verify=True)
                if response.status_code == 404:
                    await turn_context.send_activity("Patient not found !")
                elif response.status_code == 401:
                    await turn_context.send_activity("Your token has expired !"
                                                     )
                elif response.status_code == 200:
                    r_dict = json.loads(response.text)
                    trak_url = (
                        f"https://tcfhirsandbox.intersystems.com.au/t2019grxx/csp/system.Home.cls#/Direct/AW.Direct.EPR?RegistrationNo={ltxt[1]}"
                    )
                    ob_url = "https://www.google.com/"

                    try:
                        pat_name = (
                            f"{r_dict['entry'][0]['resource']['name'][0]['text']}"
                        )
                        trak_name = pat_name.upper()
                    except:
                        trak_name = "Couldn't find NAME in database"
                    try:
                        lastUpdated = (
                            f"{r_dict['entry'][0]['resource']['meta']['lastUpdated']}"
                        )
                        utc = (f"{lastUpdated[0:10]} {lastUpdated[12:19]}")
                        trak_lastUpdated = zone_convertor(utc)
                    except:
                        trak_lastUpdated = "No DATE found"
                    try:
                        trak_careProvider = (
                            f"{r_dict['entry'][0]['resource']['careProvider'][0]['display']}"
                        )
                    except:
                        trak_careProvider = "Couldn't find CARE PROVIDER in database"
                    try:
                        trak_recordNumber = (
                            f"{r_dict['entry'][0]['resource']['identifier'][1]['value']}"
                        )
                    except:
                        trak_recordNumber = "Couldn't find RECORD NUMBER in database"
                    try:
                        trak_dob = (
                            f"{r_dict['entry'][0]['resource']['birthDate']}")
                    except:
                        trak_dob = "Couldn't find DOB in database"
                    try:
                        trak_gender = (
                            f"{r_dict['entry'][0]['resource']['gender']}")
                    except:
                        trak_gender = "GENDER is not disclosed by the patient"

                    trak_allergy_url = (
                        f"https://tcfhirsandbox.intersystems.com.au/fhir/dstu2/Patient/{r_dict['entry'][0]['resource']['id']}/AllergyIntolerance"
                    )

                    allergy_resposne = requests.get(trak_allergy_url,
                                                    headers=call_header,
                                                    verify=True)
                    a_dict = json.loads(allergy_resposne.text)
                    a_total = (f"{a_dict['total']}")

                    if a_total != "0":
                        count = int(a_total)
                        index = count - 1
                        allergy_name = ""
                        allergy_reaction = ""
                        allergy_severity = ""
                        allergy_recordedDate = ""

                        while count != 0:
                            try:
                                allergy_name = allergy_name + (
                                    f"{a_dict['entry'][index]['resource']['substance']['text']}:"
                                )
                            except:
                                allergy_name = "Unknown"
                            try:
                                allergy_reaction = allergy_reaction + (
                                    f"{a_dict['entry'][index]['resource']['reaction'][0]['manifestation'][0]['text']}:"
                                )  # it is possible that there are more sublist under reaction and manifestation
                            except:
                                allergy_reaction = "No record found"
                            try:
                                allergy_severity = allergy_severity + (
                                    f"{a_dict['entry'][index]['resource']['reaction'][0]['severity']}:"
                                )
                            except:
                                allergy_severity = "No record found"
                            try:
                                utc_date = (
                                    f"{a_dict['entry'][index]['resource']['recordedDate']}|"
                                )
                                date_t = utc_date.split("T")
                                t = date_t[1].split("+")
                                dt_format = (f"{date_t[0]} {t[0]}")
                                allergy_recordedDate = allergy_recordedDate + zone_convertor(
                                    dt_format) + "|"
                            except:
                                allergy_recordedDate = "Date Unknown"
                            index = index - 1
                            count = count - 1

                        list_name = allergy_name.split(":")
                        list_reaction = allergy_reaction.split(":")
                        list_severity = allergy_severity.split(":")
                        list_date = allergy_recordedDate.split("|")
                        allergy_data = ""
                        total_allergy = int(a_total)
                        list_index = 0

                        while list_index < total_allergy:
                            allergy_data = allergy_data + (
                                f"Allergen : {list_name[list_index]}\n\nReaction : {list_reaction[list_index]}\n\nSeverity : {list_severity[list_index]}\n\nRecorded Date : {list_date[list_index]}\n\n-------------------------------------\n\n"
                            )
                            list_index += 1
                    else:
                        allergy_data = (
                            f"{trak_name} have no recorded allergies")

                    await self.__send_about_card(turn_context)

                else:
                    await turn_context.send_activity(
                        "You are not logged in. Please type 'Login' to start your session !"
                    )

            #list all providers
            elif text in ("provider", "mdt"):
                global cp_list
                cp_list = ""
                for provider in self.list_care_provider:
                    cp_list = cp_list + (
                        f"{provider['id']} - {provider['name']} \n\n")
                await self.__send_mdt_card(turn_context)

            #mention provider in the teams
            elif text in ("mention", "mention care providers"):
                if turn_context.activity.channel_id == Channels.ms_teams:
                    try:
                        members = await TeamsInfo.get_team_members(turn_context
                                                                   )
                        for provider in self.list_care_provider:
                            for member in members:
                                if member.name == provider['name']:
                                    mention = Mention(
                                        mentioned=member,
                                        text=f"<at>{member.name}</at>",
                                        type="mention",
                                    )
                                    reply_activity = MessageFactory.text(
                                        f"{mention.text}")
                                    reply_activity.entities = [
                                        Mention().deserialize(
                                            mention.serialize())
                                    ]
                                    await turn_context.send_activity(
                                        reply_activity)

                    except:
                        await turn_context.send_activity(
                            "This function is only supported in teams/channels!"
                        )

                else:
                    await turn_context.send_activity(
                        "This function is only supported in Microsoft Teams")

            elif text in ("result", "results"):
                r_name = self.dict_results['name']
                r_urn = self.dict_results['urn']
                r_url = self.dict_results['link']
                r_sender = self.dict_results['sender']
                r_message = self.dict_results['message']
                self.dict_results.clear()
                await self.__send_result_card(turn_context)

            else:
                await turn_context.send_activity(
                    "I am SORRY!, I don't understand that.")