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 answer_next_question(v, text, msg, session): resp = current_question(session.session_id) 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, v.owner_id, text, yield_responses=True) 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 form_session_handler(v, text, msg=None): """ The form session handler will use the inbound text to answer the next question in the open XformsSession for the associated contact. If no session is open, the handler passes. If multiple sessions are open, they are all closed and an error message is displayed to the user. """ sessions = XFormsSession.get_all_open_sms_sessions(v.domain, v.owner_id) if len(sessions) > 1: # If there are multiple sessions, there's no way for us to know which one this message # belongs to. So we should inform the user that there was an error and to try to restart # the survey. for session in sessions: session.end(False) session.save() send_sms_to_verified_number(v, "An error has occurred. Please try restarting the survey.") return True session = sessions[0] if len(sessions) == 1 else None if session is not None: if msg is not None: msg.workflow = session.workflow msg.reminder_id = session.reminder_id msg.xforms_session_couch_id = session._id msg.save() # If there's an open session, treat the inbound text as the answer to the next question try: resp = current_question(session.session_id) event = resp.event valid, text, error_msg = validate_answer(event, text) if valid: responses = _get_responses(v.domain, v.owner_id, text, yield_responses=True) if has_invalid_response(responses): if msg: 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, workflow=session.workflow, reminder_id=session.reminder_id, xforms_session_couch_id=session._id) else: if msg: mark_as_invalid_response(msg) send_sms_to_verified_number(v, error_msg + event.text_prompt, workflow=session.workflow, reminder_id=session.reminder_id, xforms_session_couch_id=session._id) except Exception: # Catch any touchforms errors msg_id = msg._id if msg is not None else "" logging.exception("Exception in form_session_handler for message id %s." % msg_id) send_sms_to_verified_number(v, "An error has occurred. Please try again later. If the problem persists, try restarting the survey.") return True else: return False
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 send_first_message(domain, recipient, phone_entry_or_number, session, responses, logged_subevent, workflow): # This try/except section is just here (temporarily) to support future refactors # If any of these notify, they should be replaced with a comment as to why the two are different # so that someone refactoring in the future will know that this or that param is necessary. try: if session.workflow != workflow: # see if we can eliminate the workflow arg notify_error('Exploratory: session.workflow != workflow', details={ 'session.workflow': session.workflow, 'workflow': workflow }) if session.connection_id != recipient.get_id: # see if we can eliminate the recipient arg notify_error( 'Exploratory: session.connection_id != recipient.get_id', details={ 'session.connection_id': session.connection_id, 'recipient.get_id': recipient.get_id, 'recipient': recipient }) if session.related_subevent != logged_subevent: # see if we can eliminate the logged_subevent arg notify_error( 'Exploratory: session.related_subevent != logged_subevent', details={ 'session.connection_id': session.connection_id, 'logged_subevent': logged_subevent }) except Exception: # The above running is not mission critical, so if it errors just leave a message in the log # for us to follow up on. # Absence of the message below and messages above ever notifying # will indicate that we can remove these args. notify_exception( None, "Error in section of code that's just supposed help inform future refactors" ) if toggles.ONE_PHONE_NUMBER_MULTIPLE_CONTACTS.enabled(domain): if not XFormsSessionSynchronization.claim_channel_for_session(session): send_first_message.apply_async( args=(domain, recipient, phone_entry_or_number, session, responses, logged_subevent, workflow), countdown=60) return metrics_counter('commcare.smsforms.session_started', 1, tags={ 'domain': domain, 'workflow': workflow }) if len(responses) > 0: text_responses = _responses_to_text(responses) message = format_message_list(text_responses) events = get_events_from_responses(responses) metadata = MessageMetadata( workflow=workflow, xforms_session_couch_id=session.couch_id, ) if isinstance(phone_entry_or_number, PhoneNumber): send_sms_to_verified_number(phone_entry_or_number, message, metadata, logged_subevent=logged_subevent, events=events) else: send_sms(domain, recipient, phone_entry_or_number, message, metadata) logged_subevent.completed()