示例#1
0
def fall_back(intent_request):
    # if no prev intent or prev intent is asking for symptoms
    session_attributes = helper.get_attribute(intent_request, 'sessionAttributes')
    current_intent = helper.get_attribute(intent_request, 'currentIntent')
    slots = helper.get_attribute(current_intent, 'slots')

    confirmation_status = helper.get_attribute(current_intent, 'confirmationStatus')
    # TODO: if prev intent is asking for body part
    # TODO: too many failed attempts should terminate.

    if confirmation_status == helper.ConfirmationStatus.NONE.value:
        user_utterance = intent_request['inputTranscript']
        if user_utterance == '':
            return helper.elicit_slot(session_attributes, INTENT_REPORT_SYMPTOM, slots, SLOT_SYMPTOM_ONE,
                                      msg_strings.get('CLARIFICATION'))
        message = f"your said '{user_utterance}', is that right?"
        slots[SLOT_SYMPTOM_ONE] = user_utterance
        helper.append_session_attr(session_attributes, UNKNOWN_SYMPTOM_ATTR, user_utterance)
        return helper.confirm_intent(session_attributes, INTENT_REPORT_SYMPTOM, slots, message_content=message,
                                     message_type='PlainText')
    elif confirmation_status == helper.ConfirmationStatus.DENIED.value:
        return helper.elicit_slot(session_attributes, INTENT_REPORT_SYMPTOM, slots, SLOT_SYMPTOM_ONE,
                                  msg_strings.get('AFTER_SYMPTOM_DENY'))
    else:
        return helper.elicit_slot(session_attributes, INTENT_REPORT_SYMPTOM, slots, SLOT_SYMPTOM_ONE,
                                  msg_strings.get('CLARIFICATION'))
示例#2
0
def no_symptom(intent_request):
    session_attributes = helper.get_attribute(intent_request, 'sessionAttributes')
    symptoms = helper.get_list_from_session(session_attributes, SYMPTOM_ATTR)
    current_intent = helper.get_attribute(intent_request, 'currentIntent')
    slots = helper.get_attribute(current_intent, 'slots')
    confirmation_status = helper.get_attribute(current_intent, 'confirmationStatus')
    intent_name = helper.get_attribute(current_intent, 'name')
    if confirmation_status == helper.ConfirmationStatus.NONE.value:
        if len(symptoms) == 0:
            # add confirmation for no symptoms
            return helper.confirm_intent(session_attributes, intent_name, slots,
                                         message_content=msg_strings.get('NO_SYMPTOM_CONFIRM'))
    elif confirmation_status == helper.ConfirmationStatus.DENIED.value:
        return helper.elicit_slot(session_attributes,
                                  INTENT_REPORT_SYMPTOM, slots, SLOT_SYMPTOM_ONE,
                                  message_content=msg_strings.get('ASK_SYMPTOM_DETAIL'))

    # ready to log symptoms
    user = helper.lookup_user(session_attributes)
    local_time_reported = get_current_time_for_user(user)
    unknown_symptoms = helper.get_list_from_session(session_attributes, UNKNOWN_SYMPTOM_ATTR)
    symptom_reporter.report(user.uid, local_time_reported, symptoms, unknown_symptoms)

    update_survey_completion(user.uid, local_time_reported, BOT_SYMPTOM_NAME)
    session_attributes['NextBot'] = get_next_survey_bot(user.uid, local_time_reported)

    return helper.close(session_attributes, helper.FulfillmentState.FULFILLED,
                        message_content=msg_strings.get('FINISH_SYMPTOM_REPORT'))
def verify_identity(intent_request):
    """
    Handler for the verifying identity
    :param intent_request:
    :return:
    """
    session_attributes = helper.get_attribute(intent_request,
                                              'sessionAttributes')
    current_intent = helper.get_attribute(intent_request, 'currentIntent')
    slots = helper.get_attribute(current_intent, 'slots')

    user = helper.lookup_user(session_attributes)

    zipcode_input = helper.get_attribute(slots, SLOT_ZIPCODE, None)
    if zipcode_input == user.zip_code:
        logger.info('zip code match!')
        user_local_tz = pytz.timezone(user.timezone)
        today = datetime.now(tz=timezone.utc).astimezone(user_local_tz)

        session_attributes['NextBot'] = get_next_survey_bot(user.uid, today)
        session_attributes[AUTH_RESULT_ATTR] = 'AuthSuccess'
        msg = verify_success_msg(user)
        return helper.close(session_attributes,
                            helper.FulfillmentState.FULFILLED,
                            message_content=msg,
                            message_type='PlainText')
    else:
        logger.info('zip code mismatch!')
        msg = msg_strings.get('ZIP_CODE_MISMATCH').format(zipcode_input)
        attempt_count = int(
            helper.get_attribute(session_attributes, ATTEMPT_COUNT_ATTR, "1"))
        if attempt_count >= MAX_RETRY:
            msg += msg_strings.get('ZIP_CODE_GOODBYE')
            logger.info(
                f'attempt count ({attempt_count}) reached max retry count. failed authentication.'
            )
            session_attributes[AUTH_RESULT_ATTR] = 'AuthFail'
            return helper.close(session_attributes,
                                helper.FulfillmentState.FULFILLED,
                                message_content=helper.wrap_ssml_tag(msg),
                                message_type='SSML')
        else:
            session_attributes[ATTEMPT_COUNT_ATTR] = attempt_count + 1
            msg += msg_strings.get('ZIP_CODE_RETRY')
            logger.info(
                f'attempt count ({attempt_count}) less than max retry count {MAX_RETRY}.'
            )
            return helper.elicit_slot(
                session_attributes,
                INTENT_VERIFY_IDENTITY,
                slots,
                SLOT_ZIPCODE,
                message_content=helper.wrap_ssml_tag(msg),
                message_type='SSML')
def yes_med(intent_request):
    session_attributes = helper.get_attribute(intent_request,
                                              'sessionAttributes')
    current_intent = helper.get_attribute(intent_request, 'currentIntent')
    slots = helper.get_attribute(current_intent, 'slots')
    return helper.elicit_slot(
        session_attributes,
        INTENT_MEDICATION_TIME,
        slots,
        SLOT_MED_TIME,
        '<speak>Great. When did you take your medication today?</speak>',
        message_type='SSML')
def medication_time(intent_request):
    """
    Handler for the medication time intent
    :param intent_request: lex intent request
    :return:
    """
    session_attributes = helper.get_attribute(intent_request,
                                              'sessionAttributes')
    current_intent = helper.get_attribute(intent_request, 'currentIntent')
    slots = helper.get_attribute(current_intent, 'slots')
    slot_details = helper.get_attribute(current_intent, 'slotDetails')
    intent_name = helper.get_attribute(current_intent, 'name')
    if helper.is_validation_request(intent_request):
        return validate_medication_time(intent_name, session_attributes,
                                        slot_details, slots)

    med_taken_time = slots[SLOT_MED_TIME]
    hh = int(med_taken_time.split(':')[0])
    mm = int(med_taken_time.split(':')[1])

    user = helper.lookup_user(session_attributes)
    local_time_reported = get_current_time_for_user(user)
    now_with_no_timezone = datetime.now()
    med_taken_datetime = now_with_no_timezone.replace(hour=hh,
                                                      minute=mm,
                                                      second=0)
    local_med_time = pytz.timezone(user.timezone).localize(med_taken_datetime)

    # TODO: for production, handle cases when user reported the same info multiple times.
    med_diary.log_med(user.uid,
                      time_reported=local_time_reported,
                      med_taken=True,
                      time_taken=local_med_time)

    update_survey_completion(user.uid, local_time_reported,
                             BOT_MEDICATION_NAME)
    session_attributes['NextBot'] = get_next_survey_bot(
        user.uid, local_time_reported)
    return helper.close(session_attributes,
                        helper.FulfillmentState.FULFILLED,
                        message_content=msg_strings.get('FINISH_MED_DIARY'))
 def decorate_transcript(intent_request):
     logger.debug("spoken text: {}".format(
         intent_request['inputTranscript']))
     # consider using a intercepter for this
     intent_request['sessionAttributes'] = helper.get_attribute(
         intent_request, 'sessionAttributes')
     conversation_history_serialized = intent_request[
         'sessionAttributes'].get('transcripts', '[]')
     conversation_history = json.loads(conversation_history_serialized)
     conversation_history.append({
         'time': datetime.now().isoformat(),
         'user': intent_request['inputTranscript']
     })
     intent_request['sessionAttributes']['transcripts'] = json.dumps(
         conversation_history)
示例#7
0
def validate_symptom_input(intent_name, session_attributes, slot_details, slots):
    symptom_name = slots.get(SLOT_SYMPTOM_ONE, None)
    # TODO: add support for multiple symptoms
    if not symptom_name:  # did not get symptom
        symptom_slot_detail = helper.get_attribute(slot_details, SLOT_SYMPTOM_ONE, {})
        unknown_symptom = symptom_slot_detail.get('originalValue', None)
        if unknown_symptom:
            logger.info(f'encountered unknown symptom: {unknown_symptom}')
            helper.append_session_attr(session_attributes, UNKNOWN_SYMPTOM_ATTR, unknown_symptom)
            symptom_name = unknown_symptom
            slots[SLOT_SYMPTOM_ONE] = symptom_name
        else:
            return helper.elicit_slot(session_attributes, intent_name, slots, SLOT_SYMPTOM_ONE,
                                      msg_strings.get('ASK_SYMPTOM'))

    pain_level = slots.get(SLOT_PAIN_LEVEL, None)
    if symptom_name in intensity_symptom and pain_level:
        try:
            int(pain_level)
        except ValueError:
            return helper.elicit_slot(session_attributes, intent_name, slots, SLOT_PAIN_LEVEL,
                                      msg_strings.get('PAIN_LEVEL_VALIDATION_FAILED').format(symptom_name))
        # verify within range
        if int(pain_level) < 0 or int(pain_level) > 10:
            return helper.elicit_slot(session_attributes, intent_name, slots, SLOT_PAIN_LEVEL,
                                      msg_strings.get('PAIN_LEVEL_VALIDATION_FAILED').format(symptom_name))
        else:
            # confirm intensity level if it's above threshold
            if int(pain_level) >= INTENSITY_THRESHOLD:
                msg = msg_strings.get('CONFIRM_INTENSITY').format(symptom_name, pain_level)
                return helper.confirm_intent(session_attributes, intent_name, slots, msg)
            return helper.delegate(session_attributes, slots)
    else:
        if symptom_name in localized_symptom:
            # need to distinguish which body part has the symptom
            body_part = slots.get(SLOT_BODY_PART, None)
            if not body_part:
                return helper.elicit_slot(session_attributes, intent_name, slots, SLOT_BODY_PART,
                                          msg_strings.get('ASK_SYMPTOM_BODY_PART').format(symptom_name))
            else:
                modifier = slots.get(SLOT_BODY_PART_MODIFIER, None)
                return confirm_symptom(session_attributes, intent_name, slots, symptom_name, body_part, modifier)
        else:
            return confirm_symptom(session_attributes, intent_name, slots, symptom_name)
def no_med(intent_request):
    session_attributes = helper.get_attribute(intent_request,
                                              'sessionAttributes')

    user = helper.lookup_user(session_attributes)
    current_time = get_current_time_for_user(user)
    if user.caretaker_num:
        logger.info(
            f'Will send notification to care taker: {user.caretaker_num}')
        time_str = format_only_time_to_str(current_time)
        msg = CARETAKER_MED_MISSING_MESSAGE.format(user.uid, time_str)
        send_sms(user.caretaker_num, msg)
    else:
        logger.info('No caretaker to notify.')

    med_diary.log_med(user.uid, time_reported=current_time, med_taken=False)
    update_survey_completion(user.uid, current_time, BOT_MEDICATION_NAME)
    session_attributes['NextBot'] = get_next_survey_bot(user.uid, current_time)

    return helper.close(session_attributes,
                        helper.FulfillmentState.FULFILLED,
                        message_content=msg_strings.get('DID_NOT_TAKE_MED'))
def no_later(intent_request):
    session_attributes = helper.get_attribute(intent_request, 'sessionAttributes')
    return helper.close(session_attributes, helper.FulfillmentState.FULFILLED,
                        message_content=msg_strings.get('AFTER_USER_DENY_TIME'))
示例#10
0
def report_symptom(intent_request):
    """
    Handler for the medication time intent
    :param intent_request: lex intent request
    :return:
    """
    session_attributes = helper.get_attribute(intent_request, 'sessionAttributes')
    current_intent = helper.get_attribute(intent_request, 'currentIntent')
    slots = helper.get_attribute(current_intent, 'slots')
    slot_details = helper.get_attribute(current_intent, 'slotDetails')
    intent_name = helper.get_attribute(current_intent, 'name')

    confirmation_status = helper.get_attribute(current_intent, 'confirmationStatus')
    symptom = slots.get(SLOT_SYMPTOM_ONE, None)
    body_part = slots.get(SLOT_BODY_PART, None)
    modifier = slots.get(SLOT_BODY_PART_MODIFIER, None)
    intensity = slots.get(SLOT_PAIN_LEVEL, None)
    unknown_symptoms = helper.get_list_from_session(session_attributes, UNKNOWN_SYMPTOM_ATTR)

    if confirmation_status == helper.ConfirmationStatus.NONE.value:
        if helper.is_validation_request(intent_request):
            return validate_symptom_input(intent_name, session_attributes, slot_details, slots)
    elif confirmation_status == helper.ConfirmationStatus.DENIED.value:
        # deny could be for intensity level or for symptoms

        if symptom == unknown_symptoms[-1]:
            unknown_symptoms.pop()
        session_attributes[UNKNOWN_SYMPTOM_ATTR] = json.dumps(unknown_symptoms)
        slots = {}
        return helper.elicit_slot(session_attributes, intent_name, slots, SLOT_SYMPTOM_ONE,
                                  msg_strings.get('AFTER_SYMPTOM_DENY'))

    msg = ''
    # after confirming the first symptom, say sorry to hear to show sympathy. However, only say this once per session
    if not helper.get_attribute(session_attributes, 'alreadySaidSorry'):
        if symptom in unknown_symptoms:
            msg += 'Sorry to hear that. '
        else:
            msg += 'Sorry to hear that you ' + find_descriptor_for_symptom(symptom) + ". "
        session_attributes['alreadySaidSorry'] = 'true'

    if symptom in intensity_symptom:
        # gather pain level
        if not intensity:
            msg += msg_strings.get('RATE_PAIN_PROMPT')
            return helper.elicit_slot(session_attributes, intent_name, slots, SLOT_PAIN_LEVEL, msg)
        elif int(intensity) >= INTENSITY_THRESHOLD:
            user = helper.lookup_user(session_attributes)
            local_time_reported = get_current_time_for_user(user)
            symptom_reporter.severe_symptom_report(user, local_time_reported, body_part, intensity)
            msg += f'We will notify your medical provider of your {symptom}. '
        else:
            msg += f"Got it. That's a {intensity} out of 10. "

    symptom_obj = {'symptom': symptom}
    if body_part:
        symptom_obj['bodyPart'] = body_part
    if modifier:
        symptom_obj['modifier'] = modifier
    if intensity:
        symptom_obj['intensity'] = int(intensity)
    helper.append_session_attr(session_attributes, SYMPTOM_ATTR, symptom_obj)

    msg += msg_strings.get('ADDITIONAL_SYMPTOM_QUERY')
    return helper.elicit_intent(session_attributes, message_content=msg)
示例#11
0
def yes_symptom(intent_request):
    session_attributes = helper.get_attribute(intent_request, 'sessionAttributes')
    symptoms = helper.get_list_from_session(session_attributes, SYMPTOM_ATTR)
    msg = msg_strings.get('ASK_SYMPTOM_FOLLOW_UP') if symptoms else msg_strings.get('ASK_SYMPTOM_DETAIL')
    return helper.elicit_intent(session_attributes, message_content=msg)
 def not_supported_intent_handler(intent_request):
     session_attributes = helper.get_attribute(intent_request,
                                               'sessionAttributes')
     return helper.close(session_attributes,
                         helper.FulfillmentState.FAILED,
                         message_content=msg_strings.get('NOT_SUPPORTED'))