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)
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)
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
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)
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])
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