Beispiel #1
0
def answer_next_question(v, text, msg, session):
    resp = current_question(session.session_id, domain=v.domain)
    event = resp.event
    valid, text, error_msg = validate_answer(event, text, v)

    # metadata to be applied to the reply message
    outbound_metadata = MessageMetadata(
        workflow=session.workflow,
        reminder_id=session.reminder_id,
        xforms_session_couch_id=session._id,
    )

    if valid:
        responses = get_responses(v.domain, session.session_id, text)

        if has_invalid_response(responses):
            mark_as_invalid_response(msg)

        text_responses = _responses_to_text(responses)
        if len(text_responses) > 0:
            response_text = format_message_list(text_responses)
            send_sms_to_verified_number(v,
                                        response_text,
                                        metadata=outbound_metadata)
    else:
        mark_as_invalid_response(msg)
        response_text = "%s %s" % (error_msg, event.text_prompt)
        send_sms_to_verified_number(v,
                                    response_text,
                                    metadata=outbound_metadata)
Beispiel #2
0
def answer_next_question(v, text, msg, session):
    resp = current_question(session.session_id, domain=v.domain)
    event = resp.event
    valid, text, error_msg = validate_answer(event, text, v)

    # metadata to be applied to the reply message
    outbound_metadata = MessageMetadata(
        workflow=session.workflow,
        reminder_id=session.reminder_id,
        xforms_session_couch_id=session._id,
    )

    if valid:
        responses = get_responses(v.domain, session.session_id, text)

        if has_invalid_response(responses):
            mark_as_invalid_response(msg)

        text_responses = _responses_to_text(responses)
        if len(text_responses) > 0:
            response_text = format_message_list(text_responses)
            send_sms_to_verified_number(v, response_text, 
                metadata=outbound_metadata)
    else:
        mark_as_invalid_response(msg)
        response_text = "%s %s" % (error_msg, event.text_prompt)
        send_sms_to_verified_number(v, response_text, 
            metadata=outbound_metadata)
Beispiel #3
0
def q_and_a(testcase, answer, expected_response, domain=DOMAIN, 
            contact_id=CONTACT_ID, print_output=True):
            
    responses = get_responses(SMSLog(couch_recipient=contact_id, domain=domain,
                                     text=answer))
    [answer_back] = responses
    testcase.assertEqual(expected_response, answer_back, 
                         "Response to '%s' expected '%s' but was '%s'" % \
                         (answer, expected_response, answer_back))
    if print_output:
        print "%s -> %s" % (answer, answer_back)
Beispiel #4
0
def _handle_structured_sms(domain,
                           args,
                           contact_id,
                           session_id,
                           first_question,
                           verified_number,
                           xpath_answer=None):

    form_complete = False
    current_question = first_question
    internal_error_msg = get_message(MSG_TOUCHFORMS_DOWN, verified_number)

    used_named_args = xpath_answer is not None
    answer_num = 0
    while not form_complete:
        if current_question.is_error:
            error_msg = current_question.text_prompt or internal_error_msg
            raise StructuredSMSException(response_text=error_msg,
                                         xformsresponse=current_question)

        xpath = current_question.event._dict["binding"]
        if used_named_args and xpath in xpath_answer:
            valid, answer, error_msg = validate_answer(current_question.event,
                                                       xpath_answer[xpath],
                                                       verified_number)
            if not valid:
                raise StructuredSMSException(response_text=error_msg,
                                             xformsresponse=current_question)
        elif not used_named_args and answer_num < len(args):
            answer = args[answer_num].strip()
            valid, answer, error_msg = validate_answer(current_question.event,
                                                       answer, verified_number)
            if not valid:
                raise StructuredSMSException(response_text=error_msg,
                                             xformsresponse=current_question)
        else:
            # We're out of arguments, so try to leave each remaining question
            # blank and continue
            answer = ""
            if current_question.event._dict.get("required", False):
                error_msg = get_message(MSG_FIELD_REQUIRED, verified_number)
                raise StructuredSMSException(response_text=error_msg,
                                             xformsresponse=current_question)

        responses = get_responses(domain, session_id, answer)
        current_question = responses[-1]

        form_complete = is_form_complete(current_question)
        answer_num += 1
Beispiel #5
0
def q_and_a(testcase,
            answer,
            expected_response,
            domain=DOMAIN,
            contact_id=CONTACT_ID,
            print_output=True):

    responses = get_responses(
        SMSLog(couch_recipient=contact_id, domain=domain, text=answer))
    [answer_back] = responses
    testcase.assertEqual(expected_response, answer_back,
                         "Response to '%s' expected '%s' but was '%s'" % \
                         (answer, expected_response, answer_back))
    if print_output:
        print "%s -> %s" % (answer, answer_back)
Beispiel #6
0
def _handle_structured_sms(domain, args, contact_id, session_id,
    first_question, verified_number, xpath_answer=None):

    form_complete = False
    current_question = first_question
    internal_error_msg = get_message(MSG_TOUCHFORMS_DOWN, verified_number)

    used_named_args = xpath_answer is not None
    answer_num = 0
    while not form_complete:
        if current_question.is_error:
            error_msg = current_question.text_prompt or internal_error_msg
            raise StructuredSMSException(response_text=error_msg,
                xformsresponse=current_question)

        xpath = current_question.event._dict["binding"]
        if used_named_args and xpath in xpath_answer:
            valid, answer, error_msg = validate_answer(current_question.event,
                xpath_answer[xpath], verified_number)
            if not valid:
                raise StructuredSMSException(response_text=error_msg,
                    xformsresponse=current_question)
        elif not used_named_args and answer_num < len(args):
            answer = args[answer_num].strip()
            valid, answer, error_msg = validate_answer(current_question.event,
                answer, verified_number)
            if not valid:
                raise StructuredSMSException(response_text=error_msg,
                    xformsresponse=current_question)
        else:
            # We're out of arguments, so try to leave each remaining question
            # blank and continue
            answer = ""
            if current_question.event._dict.get("required", False):
                error_msg = get_message(MSG_FIELD_REQUIRED,
                    verified_number)
                raise StructuredSMSException(response_text=error_msg,
                    xformsresponse=current_question)

        responses = get_responses(domain, session_id, answer)
        current_question = responses[-1]

        form_complete = is_form_complete(current_question)
        answer_num += 1
Beispiel #7
0
def answer_next_question(verified_number, text, msg, session, subevent_id):
    resp = FormplayerInterface(session.session_id,
                               verified_number.domain).current_question()
    event = resp.event
    valid, text, error_msg = validate_answer(event, text, verified_number)

    # metadata to be applied to the reply message
    outbound_metadata = MessageMetadata(
        workflow=session.workflow,
        reminder_id=session.reminder_id,
        xforms_session_couch_id=session._id,
        messaging_subevent_id=subevent_id,
    )

    if valid:
        responses = get_responses(verified_number.domain, session.session_id,
                                  text)

        if has_invalid_response(responses):
            mark_as_invalid_response(msg)

        text_responses = _responses_to_text(responses)
        events = get_events_from_responses(responses)
        if len(text_responses) > 0:
            response_text = format_message_list(text_responses)
            send_sms_to_verified_number(verified_number,
                                        response_text,
                                        metadata=outbound_metadata,
                                        events=events)
    else:
        mark_as_invalid_response(msg)
        response_text = "%s %s" % (error_msg, event.text_prompt)
        send_sms_to_verified_number(verified_number,
                                    response_text,
                                    metadata=outbound_metadata,
                                    events=[event])
Beispiel #8
0
def incoming(phone_number, text, backend_api):
    phone_without_plus = str(phone_number)
    if phone_without_plus[0] == "+":
        phone_without_plus = phone_without_plus[1:]
    phone_with_plus = "+" + phone_without_plus
    
    # Circular Import
    from corehq.apps.reminders.models import SurveyKeyword
    
    v = VerifiedNumber.view("sms/verified_number_by_number",
        key=phone_without_plus,
        include_docs=True
    ).one()
    
    # Log message in message log
    msg = SMSLog(
        phone_number    = phone_with_plus,
        direction       = INCOMING,
        date            = datetime.utcnow(),
        text            = text,
        backend_api     = backend_api
    )
    if v is not None:
        msg.couch_recipient_doc_type    = v.owner_doc_type
        msg.couch_recipient             = v.owner_id
        msg.domain                      = v.domain
    msg.save()
    
    # Handle incoming sms
    if v is not None:
        session = XFormsSession.view("smsforms/open_sessions_by_connection",
                                     key=[v.domain, v.owner_id],
                                     include_docs=True).one()
        
        text_words = text.upper().split()
        
        # Respond to "#START <keyword>" command
        if len(text_words) > 0 and text_words[0] == "#START":
            if len(text_words) > 1:
                sk = SurveyKeyword.get_keyword(v.domain, text_words[1])
                if sk is not None:
                    if session is not None:
                        session.end(False)
                        session.save()
                    start_session_from_keyword(sk, v)
                else:
                    send_sms_to_verified_number(v, "Survey '" + text_words[1] + "' not found.")
            else:
                send_sms_to_verified_number(v, "Usage: #START <keyword>")
        
        # Respond to "#STOP" keyword
        elif len(text_words) > 0 and text_words[0] == "#STOP":
            if session is not None:
                session.end(False)
                session.save()
        
        # Respond to "#CURRENT" keyword
        elif len(text_words) > 0 and text_words[0] == "#CURRENT":
            if session is not None:
                resp = current_question(session.session_id)
                send_sms_to_verified_number(v, resp.event.text_prompt)
        
        # Respond to unknown command
        elif len(text_words) > 0 and text_words[0][0] == "#":
            send_sms_to_verified_number(v, "Unknown command '" + text_words[0] + "'")
        
        # If there's an open session, treat the inbound text as the answer to the next question
        elif session is not None:
            resp = current_question(session.session_id)
            event = resp.event
            valid = False
            error_msg = None
            
            # Validate select questions
            if event.datatype == "select":
                try:
                    answer = int(text.strip())
                    if answer >= 1 and answer <= len(event._dict["choices"]):
                        valid = True
                except Exception:
                    pass
                if not valid:
                    error_msg = "Invalid Response. " + event.text_prompt
            
            # For now, anything else passes
            else:
                valid = True
            
            if valid:
                responses = get_responses(msg)
                if len(responses) > 0:
                    response_text = format_message_list(responses)
                    send_sms_to_verified_number(v, response_text)
            else:
                send_sms_to_verified_number(v, error_msg)
        
        # Try to match the text against a keyword to start a survey
        elif len(text_words) > 0:
            sk = SurveyKeyword.get_keyword(v.domain, text_words[0])
            if sk is not None:
                start_session_from_keyword(sk, v)
    else:
        #TODO: Registration via SMS
        pass