Merge branch 'philip/ussd_session_resumption' into 'master'
Add barebone session resumption feature See merge request grassrootseconomics/cic-internal-integration!60
This commit is contained in:
commit
650472252d
@ -14,7 +14,7 @@ from cic_ussd.db.models.user import User
|
|||||||
from cic_ussd.db.models.ussd_session import UssdSession
|
from cic_ussd.db.models.ussd_session import UssdSession
|
||||||
from cic_ussd.db.models.task_tracker import TaskTracker
|
from cic_ussd.db.models.task_tracker import TaskTracker
|
||||||
from cic_ussd.menu.ussd_menu import UssdMenu
|
from cic_ussd.menu.ussd_menu import UssdMenu
|
||||||
from cic_ussd.processor import custom_display_text, process_request
|
from cic_ussd.processor import custom_display_text, process_request, retrieve_most_recent_ussd_session
|
||||||
from cic_ussd.redis import InMemoryStore
|
from cic_ussd.redis import InMemoryStore
|
||||||
from cic_ussd.session.ussd_session import UssdSession as InMemoryUssdSession
|
from cic_ussd.session.ussd_session import UssdSession as InMemoryUssdSession
|
||||||
from cic_ussd.validator import check_known_user, validate_response_type
|
from cic_ussd.validator import check_known_user, validate_response_type
|
||||||
@ -60,7 +60,8 @@ def create_ussd_session(
|
|||||||
phone: str,
|
phone: str,
|
||||||
service_code: str,
|
service_code: str,
|
||||||
user_input: str,
|
user_input: str,
|
||||||
current_menu: str) -> InMemoryUssdSession:
|
current_menu: str,
|
||||||
|
session_data: Optional[dict] = None) -> InMemoryUssdSession:
|
||||||
"""
|
"""
|
||||||
Creates a new ussd session
|
Creates a new ussd session
|
||||||
:param external_session_id: Session id value provided by AT
|
:param external_session_id: Session id value provided by AT
|
||||||
@ -73,6 +74,8 @@ def create_ussd_session(
|
|||||||
:type user_input: str
|
:type user_input: str
|
||||||
:param current_menu: Menu name that is currently being displayed on the ussd session
|
:param current_menu: Menu name that is currently being displayed on the ussd session
|
||||||
:type current_menu: str
|
:type current_menu: str
|
||||||
|
:param session_data: Any additional data that was persisted during the user's interaction with the system.
|
||||||
|
:type session_data: dict.
|
||||||
:return: ussd session object
|
:return: ussd session object
|
||||||
:rtype: Session
|
:rtype: Session
|
||||||
"""
|
"""
|
||||||
@ -81,7 +84,8 @@ def create_ussd_session(
|
|||||||
msisdn=phone,
|
msisdn=phone,
|
||||||
user_input=user_input,
|
user_input=user_input,
|
||||||
state=current_menu,
|
state=current_menu,
|
||||||
service_code=service_code
|
service_code=service_code,
|
||||||
|
session_data=session_data
|
||||||
)
|
)
|
||||||
return session
|
return session
|
||||||
|
|
||||||
@ -126,7 +130,9 @@ def create_or_update_session(
|
|||||||
phone=phone,
|
phone=phone,
|
||||||
service_code=service_code,
|
service_code=service_code,
|
||||||
user_input=user_input,
|
user_input=user_input,
|
||||||
current_menu=current_menu)
|
current_menu=current_menu,
|
||||||
|
session_data=session_data
|
||||||
|
)
|
||||||
return ussd_session
|
return ussd_session
|
||||||
|
|
||||||
|
|
||||||
@ -338,7 +344,19 @@ def process_menu_interaction_requests(chain_str: str,
|
|||||||
user_input=user_input
|
user_input=user_input
|
||||||
)
|
)
|
||||||
|
|
||||||
|
last_ussd_session = retrieve_most_recent_ussd_session(phone_number=user.phone_number)
|
||||||
|
|
||||||
|
if last_ussd_session:
|
||||||
# create or update the ussd session as appropriate
|
# create or update the ussd session as appropriate
|
||||||
|
ussd_session = create_or_update_session(
|
||||||
|
external_session_id=external_session_id,
|
||||||
|
phone=phone_number,
|
||||||
|
service_code=service_code,
|
||||||
|
user_input=user_input,
|
||||||
|
current_menu=current_menu.get('name'),
|
||||||
|
session_data=last_ussd_session.session_data
|
||||||
|
)
|
||||||
|
else:
|
||||||
ussd_session = create_or_update_session(
|
ussd_session = create_or_update_session(
|
||||||
external_session_id=external_session_id,
|
external_session_id=external_session_id,
|
||||||
phone=phone_number,
|
phone=phone_number,
|
||||||
|
@ -6,7 +6,7 @@ from typing import Optional
|
|||||||
|
|
||||||
# third party imports
|
# third party imports
|
||||||
import celery
|
import celery
|
||||||
from cic_types.models.person import Person
|
from sqlalchemy import desc
|
||||||
from tinydb.table import Document
|
from tinydb.table import Document
|
||||||
|
|
||||||
# local imports
|
# local imports
|
||||||
@ -315,6 +315,16 @@ def process_start_menu(display_key: str, user: User):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def retrieve_most_recent_ussd_session(phone_number: str) -> UssdSession:
|
||||||
|
# get last ussd session based on user phone number
|
||||||
|
last_ussd_session = UssdSession.session\
|
||||||
|
.query(UssdSession)\
|
||||||
|
.filter_by(msisdn=phone_number)\
|
||||||
|
.order_by(desc(UssdSession.created))\
|
||||||
|
.first()
|
||||||
|
return last_ussd_session
|
||||||
|
|
||||||
|
|
||||||
def process_request(user_input: str, user: User, ussd_session: Optional[dict] = None) -> Document:
|
def process_request(user_input: str, user: User, ussd_session: Optional[dict] = None) -> Document:
|
||||||
"""This function assesses a request based on the user from the request comes, the session_id and the user's
|
"""This function assesses a request based on the user from the request comes, the session_id and the user's
|
||||||
input. It determines whether the request translates to a return to an existing session by checking whether the
|
input. It determines whether the request translates to a return to an existing session by checking whether the
|
||||||
@ -337,7 +347,23 @@ def process_request(user_input: str, user: User, ussd_session: Optional[dict] =
|
|||||||
return UssdMenu.find_by_name(name=successive_state)
|
return UssdMenu.find_by_name(name=successive_state)
|
||||||
else:
|
else:
|
||||||
if user.has_valid_pin():
|
if user.has_valid_pin():
|
||||||
|
last_ussd_session = retrieve_most_recent_ussd_session(phone_number=user.phone_number)
|
||||||
|
|
||||||
|
key = create_cached_data_key(
|
||||||
|
identifier=blockchain_address_to_metadata_pointer(blockchain_address=user.blockchain_address),
|
||||||
|
salt='cic.person'
|
||||||
|
)
|
||||||
|
user_metadata = get_cached_data(key=key)
|
||||||
|
|
||||||
|
if last_ussd_session:
|
||||||
|
# get last state
|
||||||
|
last_state = last_ussd_session.state
|
||||||
|
logg.debug(f'LAST USSD SESSION STATE: {last_state}')
|
||||||
|
# if last state is account_creation_prompt and metadata exists, show start menu
|
||||||
|
if last_state == 'account_creation_prompt' and user_metadata is not None:
|
||||||
return UssdMenu.find_by_name(name='start')
|
return UssdMenu.find_by_name(name='start')
|
||||||
|
else:
|
||||||
|
return UssdMenu.find_by_name(name=last_state)
|
||||||
else:
|
else:
|
||||||
if user.failed_pin_attempts >= 3 and user.get_account_status() == AccountStatus.LOCKED.name:
|
if user.failed_pin_attempts >= 3 and user.get_account_status() == AccountStatus.LOCKED.name:
|
||||||
return UssdMenu.find_by_name(name='exit_pin_blocked')
|
return UssdMenu.find_by_name(name='exit_pin_blocked')
|
||||||
|
Loading…
Reference in New Issue
Block a user