def post(self): post_data = request.get_json() or request.form session_id = post_data.get('sessionId') phone_number = post_data.get('phoneNumber') user_input = post_data.get('text') service_code = post_data.get('serviceCode') if phone_number: user = get_user_by_phone(phone_number) # api chains all inputs that came through with * latest_input = user_input.split('*')[-1] if None in [user, session_id]: current_menu = UssdMenu.find_by_name('exit_not_registered') text = menu_display_text_in_lang(current_menu, user) else: current_menu = UssdProcessor.process_request(session_id, latest_input, user) ussd_session = create_or_update_session(session_id, user, current_menu, user_input, service_code) text = UssdProcessor.custom_display_text(current_menu, ussd_session) if "CON" not in text and "END" not in text: raise Exception("no menu found. text={}, user={}, menu={}, session={}".format(text, user.id, current_menu.name, ussd_session.id)) if len(text) > 164: print(f"Warning, text has length {len(text)}, display may be truncated") db.session.commit() else: current_menu = UssdMenu.find_by_name('exit_invalid_request') text = menu_display_text_in_lang(current_menu, None) return make_response(text), 200
def process_request(session_id: str, user_input: str, user: User) -> UssdMenu: session: Optional[UssdSession] = UssdSession.query.filter_by( session_id=session_id).first() # returning session if session: if user_input == "": return UssdMenu.find_by_name('exit_invalid_input') elif user_input == '0': return UssdMenu.find_by_name(session.state).parent() else: new_state = KenyaUssdProcessor.next_state( session, user_input, user) return UssdMenu.find_by_name(new_state) # new session else: if user.has_valid_pin(): return UssdMenu.find_by_name('start') else: if user.failed_pin_attempts is not None and user.failed_pin_attempts >= 3: return UssdMenu.find_by_name('exit_pin_blocked') elif user.preferred_language is None: return UssdMenu.find_by_name('initial_language_selection') else: return UssdMenu.find_by_name('initial_pin_entry')
def post(self): post_data = request.get_json() or request.form session_id = post_data.get('sessionId') phone_number = post_data.get('phoneNumber') user_input = post_data.get('text') service_code = post_data.get('serviceCode') # enforce only one single service code that can access the ussd state machine # through the endpoint if config.USSD_VALID_SERVICE_CODE != service_code: response = 'END ' response += i18n.t( 'ussd.kenya.invalid_service_code', valid_service_code=config.USSD_VALID_SERVICE_CODE, locale='sw') response += "\n" response += i18n.t( 'ussd.kenya.invalid_service_code', valid_service_code=config.USSD_VALID_SERVICE_CODE, locale='en') return make_response(response, 200) elif phone_number: user = get_user_by_phone(phone_number, 'KE') # api chains all inputs that came through with * latest_input = user_input.split('*')[-1] if None in [user, session_id]: user_without_transfer_account = create_user_without_transfer_account( phone_number) current_menu = UssdMenu.find_by_name( 'initial_language_selection') ussd_session = create_or_update_session( session_id=session_id, user=user_without_transfer_account, user_input=latest_input, service_code=service_code, current_menu=current_menu) text = KenyaUssdProcessor.custom_display_text( current_menu, ussd_session) else: current_menu = KenyaUssdProcessor.process_request( session_id, latest_input, user) ussd_session = create_or_update_session( session_id, user, current_menu, user_input, service_code) text = KenyaUssdProcessor.custom_display_text( current_menu, ussd_session) if "CON" not in text and "END" not in text: raise Exception( "no menu found. text={}, user={}, menu={}, session={}". format(text, user.id, current_menu.name, ussd_session.id)) if len(text) > 164: print( f"Warning, text has length {len(text)}, display may be truncated" ) db.session.commit() else: current_menu = UssdMenu.find_by_name('exit_invalid_request') text = menu_display_text_in_lang(current_menu, None) return make_response(text), 200