def start(update, context): # Check for duplicate registration user = Database().session.query(User).filter_by( chat_id=str(update.effective_chat.id)).first() if user is not None: # User exists, so let 'em know msg_txt = 'You have already been registered! Please talk to your AWW [AWW name] on [AWW phone number] if you have any doubts.' if settings.HINDI: msg_txt = 'आप पहले से ही पंजीकृत हैं! यदि आपको कोई संदेह है तो कृपया [AWW phone number] पर अपनी आंगनवाड़ी कार्यकर्ता [AWW name] से बात करें।' msg_txt = msg_txt.replace('[AWW name]', user.aww) msg_txt = msg_txt.replace('[AWW phone number]', user.aww_number) send_text_reply(msg_txt, update, state='registration_duplicate') return ConversationHandler.END if settings.HINDI: send_text_reply( 'नमस्ते और आपका स्वागत है। मेरा नाम पोशन दीदी है और मैं इस समय विकसित हो रही हूँ।', update, state='registration_1') send_text_reply( f'क्या मैं आपको {update.message.from_user.first_name} कह सकती हूं?', update, state='registration_1') else: send_text_reply( 'Hello and welcome. My name is Poshan Didi and I am currently under development.', update, state='registration_1') send_text_reply( f'Can I call you {update.message.from_user.first_name}?', update, state='registration_1') return CONFIRM_NAME
def _check_pending(update, context, none_pending_msg): if not Database().nurse_queue_pending(): send_text_reply(none_pending_msg, update) logger.info( f'[{beneficiary_bot.get_chat_id(update, context)}] - no pending nurse messages....') return False return True
def _awc_code_error(update): if settings.HINDI: send_text_reply('आंगनवाड़ी सेण्टर कोड में 11 अंक होने चाहिए। आपके आंगनवाड़ी सेंटर का कोड क्या है?', update, state='registration_7x') else: send_text_reply('There should be 11 digits in the AWC code. What is the AWC code?', update, state='registration_7x') return AWC_CODE
def wrong_phone_number(update, context): _log_msg(update.message.text, 'user', update, state='registration_5b') if settings.HINDI: send_text_reply( f'आपका फोन नंबर क्या है? कृपया उसे निम्न प्रारूप में दर्ज करें: + 91dddddddddd, जहां प्रत्येक d एक संख्या है।', update, state='registration_5b') else: send_text_reply( f'What is your phone number? Please enter it in the following format: +91dddddddddd, where each d is a number', update, state='registration_5b') return PHONE_NUMBER
def _handle_global_reset(update, context): msgs, imgs, state_id, state_name = _get_menu_for_user(context) _save_user_state(update.effective_chat.id, state_id, state_name) msgs = [replace_template(m, context) for m in msgs] for msg in msgs: send_text_reply(msg, update) if imgs: for img in imgs: send_image_reply(prepend_img_path(img), update)
def wrong_child_birthday(update, context): _log_msg(update.message.text, 'user', update, state='registration_4b') if settings.HINDI: send_text_reply( f"{context.user_data['child_name']} की जन्म की तारिख कब की है? कृपया उस संख्या को इस प्रारूप में लिखें: YYYY-MM-DD (साल-महीना-महीने का दिन)", update, state='registration_4b') else: send_text_reply( f"What is the birthday for {context.user_data['child_name']}? Please enter in this format: YYYY-MM-DD", update, state='registration_4b') return ASK_CHILD_BIRTHDAY
def skip(update,context): if not _check_pending(update,context,"No pending messages to skip!"): return escalation = Database().get_nurse_queue_first_pending() Database().nurse_queue_mark_answered(escalation.chat_src_id) send_text_reply( f"Ok. Successfully skipped one pending message from {escalation.first_name} ({escalation.chat_src_id}).", update) _check_nurse_queue(context)
def wrong_aww_number(update, context): _log_msg(update.message.text, 'user', update, state='registration_6b') if settings.HINDI: send_text_reply( f'{context.user_data["aww"]} के लिए फ़ोन नंबर क्या है? कृपया इसे निम्न प्रारूप में दर्ज करें: + 91dddddddddd, जहां प्रत्येक d एक संख्या है', update, state='registration_6') else: send_text_reply( f'What is the phone number for {context.user_data["aww"]}? Please enter it in the following format: +91dddddddddd, where each d is a number', update, state='registration_6') return AWW_NUMBER
def _save_name(update, context, name): # Don't save because we will have saved input before this is called. # _log_msg(update.message.text, 'user', update, state='registration') context.user_data['preferred_name'] = name if settings.HINDI: send_text_reply( f'ठीक है, धन्यवाद {name}। कृपया मुझे बताएं कि मुझे आपके बच्चे को क्या कहना चाहिए (उनका दिया गया पहला नाम ही काफी रहेगा)।', update, state='registration_2') else: send_text_reply( f'Ok, thank you {name}. Please tell me what I should call your child (just a first name is fine).', update, state='registration_2') return ASK_CHILD_NAME
def phone_number(update, context): _log_msg(update.message.text, 'user', update, state='registration_5') # Our regex lets the users put in white space, so strip it all out # (this doesnt actually matter, but is nice) context.user_data['phone_number'] = update.message.text.replace(' ', '') if settings.HINDI: send_text_reply( f'बहुत अच्छे! बस कुछ सवाल। आपकी आंगनवाड़ी कार्यकर्ता का क्या नाम है?', update, state='registration_5') else: send_text_reply( f'Ok, last few questions. What is the name of the AWW here?', update, state='registration_5') return AWW_LIST
def ask_awc_code(update, context): _log_msg(update.message.text, 'user', update, state='registration_7') # Our regex lets the users put in white space, so strip it all out # (this doesnt actually matter, but is nice) context.user_data['aww_number'] = update.message.text.replace(' ', '') if settings.HINDI: send_text_reply( f'धन्यवाद! अंतिम प्रश्न: आपके आंगनवाड़ी सेंटर का कोड क्या है?', update, state='registration_7') else: send_text_reply( f'Thanks! Last question: what is the AWC code?', update, state='registration_7') return AWC_CODE
def _set_user_state(update, chat_id, new_state): # Set the state for the user manually our_user = Database().session.query(User).filter_by(chat_id=str(chat_id)).first() sm = beneficiary_bot.get_sm_from_track(our_user.track) try: state_id = sm.get_state_id_from_state_name(new_state) except ValueError: send_text_reply( f"Usage details: /state <new_state_name>\n '{new_state}' not recognized as a valid state.", update) return False our_user.current_state = state_id our_user.current_state_name = new_state Database().commit() return True
def set_state(update, context): # Save the mssage the nurse sent in logger.warning('Set state called!') current_msg = Database().get_nurse_queue_first_pending() try: chat_id = current_msg.chat_src_id except AttributeError: chat_id = update.effective_chat.id _log_msg(update.message.text, 'nurse', update, state=Database().get_state_name_from_chat_id(chat_id)) # Ensure we have pending messages if not _check_pending(update, context, "The state command can only be used when there is a pending message. There are currently no pending messages"): return # Check syntax of the command try: cmd_parts = update.message.text.split() if len(cmd_parts) < 2: raise Exception() new_state = ''.join(cmd_parts[1:]) except: send_text_reply( "Usage details: /state <new_state_name>", update) return # Update the DB with the correct message text if not _set_user_state(update, chat_id, new_state): # failed to find the state the nurse requested return our_user = Database().session.query(User).filter_by(chat_id=str(chat_id)).first() sm = beneficiary_bot.get_sm_from_track(our_user.track) msgs, imgs, _, _, _ = sm.get_msg_and_next_state( new_state, our_user.child_gender) beneficiary_bot.fetch_user_data(chat_id, context) msgs, imgs = beneficiary_bot.replace_custom_message(msgs, imgs, context) _send_message_to_queue( update, context, msgs, imgs ) # Tell the nurse and check the queue send_text_reply( f"Ok. State successfully set to {new_state} and message sent to the user.", update) Database().nurse_queue_mark_answered(current_msg.chat_src_id) _check_nurse_queue(context)
def ask_child_name(update, context): _log_msg(update.message.text, 'user', update, state='registration_3') name = context.user_data['preferred_name'] context.user_data['child_name'] = update.message.text if settings.HINDI: send_text_reply( f'ठीक है, धन्यवाद {name} - मैं आपके बच्चे को {update.message.text} के नाम से बुलाऊंगी। बस हो गया- कुछ और प्रश्न रह रहे हैं।\n\n' f'आपके बच्चे का लिंग क्या है?\n' f'1) लड़की\n' f'2) लड़का', update, state='registration_3') else: send_text_reply( f'Ok, thank you {name}--I will refer to your child as {update.message.text}.\n\nAlmost done--just a few more questions. ' f'What is the gender of your child?\n1) Girl\n2) Boy', update, state='registration_3') return ASK_CHILD_GENDER
def _save_state_and_process(update, context, msgs, imgs, state_id, state_name): current_state_id, _ = _get_current_state_from_context(context) logger.info( f'[{get_chat_id(update, context)}] - current state: {current_state_id} -> next state: {state_id}' ) # logger.info(f'[{update.effective_chat.id}] - next state: {state.msg_id}') context.user_data['current_state'] = state_id _save_user_state(update.effective_chat.id, state_id, state_name) msgs = [replace_template(m, context) for m in msgs] for msg in msgs: send_text_reply(msg, update) if imgs: for img in imgs: send_image_reply(prepend_img_path(img), update)
def set_super_state(update, context): # Save the mssage the nurse sent in logger.warning('Set SUPER state called in GOD mode!') _log_msg(update.message.text, 'GOD', update) # Check syntax of the command try: cmd_parts = update.message.text.split() if len(cmd_parts) != 3: raise Exception() chat_id = cmd_parts[1] new_state = cmd_parts[2] except: send_text_reply( "Usage details for GOD mode: /state <chat_id> <new_state_name>", update) return # Update the DB with the correct message text if not _set_user_state(update, chat_id, new_state): # failed to find the state the nurse requested return our_user = Database().session.query(User).filter_by(chat_id=str(chat_id)).first() sm = beneficiary_bot.get_sm_from_track(our_user.track) msgs, imgs, _, _, _ = sm.get_msg_and_next_state( new_state, our_user.child_gender) beneficiary_bot.fetch_user_data(chat_id, context) msgs, imgs = beneficiary_bot.replace_custom_message(msgs, imgs, context) _send_message_to_chat_id( update, context, chat_id, msgs) _send_images_to_chat_id( update, context, chat_id, imgs) # Tell the nurse and check the queue send_text_reply( f"Ok. State successfully set to {new_state} and message sent to the user.", update) _check_nurse_queue(context)
def thanks(update, context): _log_msg(update.message.text, 'user', update, state='registration_final') try: awc_code = int(update.message.text) except: return _awc_code_error(update) if len(str(awc_code)) != 11: return _awc_code_error(update) context.user_data['awc_code'] = update.message.text # HACK: to calculate the cohort d1 = datetime(2019, 6, 26) d2 = datetime.utcnow() monday1 = (d1 - timedelta(days=d1.weekday())) monday2 = (d2 - timedelta(days=d2.weekday())) cohort = (monday2 - monday1).days // 7 # SAVE THE USER new_user = User( chat_id=update.effective_chat.id, first_name=context.user_data['preferred_name'], last_name=update.message.from_user.last_name, track=context.user_data['track'], phone_number=context.user_data['phone_number'], child_name=context.user_data['child_name'], child_gender=context.user_data['child_gender'], child_birthday=datetime.strptime( context.user_data['child_birthday'], '%Y-%m-%d'), current_state='echo', current_state_name='echo', aww=context.user_data['aww'], aww_number=context.user_data['aww_number'], awc_code=context.user_data['awc_code'], registration_date=datetime.utcnow(), cohort=cohort, test_user=False ) Database().insert(new_user) if settings.HINDI: send_text_reply( "धन्यवाद! अब आप पंजीकृत हैं।", update, state='registration_final') send_text_reply( "यदि आप मेरे द्वारा पहला संदेश भेजने से पहले थोड़ा अभ्यास करना चाहते हैं, तो कृपया 1 से 10 के बीच कोई भी संख्या दर्ज करें और मैं आपको बताउंगी कि मैंने क्या समझा।", update, state='registration_final') send_text_reply( "कृपया अपने पहले संदेश की प्रतीक्षा करें, जो अगले 7 दिनों के भीतर मेरे द्वारा आना चाहिए। आप मेरे द्वारा भेजे गए किसी भी सन्देश को फिर से पा सकते हैं, बस किसी भी समय हेल्लो टाइप करके!", update, state='registration_final') else: send_text_reply( "Thank you! You're registered. Please wait for your first message, that should come within the next 7 days. If you want to practice before I sent you the first message, please enter a number between 1 to 10 and I will tell you what I understood. You can access all content I have sent you after that just by typing hello at any time!", update, state='registration_final') return ConversationHandler.END
def send_next_modules(update, context): logger.warning('Send next modules called in GOD mode!') _log_msg(update.message.text, 'GOD', update) # Check syntax try: cmd_parts = update.message.text.split() if len(cmd_parts) != 2: logger.warning('Send next modules: wrong number of args') raise Exception() cohort = cmd_parts[1] except: send_text_reply( 'Usage details for send next modules: /send_next_modules <cohort>, where the cohort is the group to increment', update) return user_count = send_next_module( update, context, cohort) return send_text_reply( f'Successfully changed the state for {user_count} users!', update)
def send_global_msg(update,context): # pre_sign_off="मेरे साथ इस गतिविधि में भाग लेने और बात करने के लिए धन्यवाद! पोशन दीदी के साथ बात-चीत करने का परीक्षण अक्टूबर 15, 2019 को समाप्त हो जाएगा जिसके बाद मैं उपलब्ध नहीं रहूंगी। यदि आपके पास मेरे लिए कोई और प्रश्न हैं, तो कृपया अंतिम तिथि से पहले मुझे संदेश भेजें।" sign_off="आप पोशन दीदी से बात करने वाले पहले कुछ उपयोगकर्ताओं में से एक हैं! अब हम इस परीक्षण अवधि के अंत तक पहुँच चुके हैं और इसलिए मुझे ऑफ़लाइन जाना होगा यानि की अब मैं उपलब्ध नहीं रहूंगी। मेरे साथ बात करके इस गतिविधि में भाग लेने के लिए धन्यवाद! यदि आपके बच्चे से सम्बंधित आपको पोषण या स्वास्थ्य पर अधिक प्रश्न हैं तो कृपया अपनी आंगनवाड़ी कार्यकर्ता [AWW name] से संपर्क करें।" users = Database().session.query(User) n = 0 for user in users: if user.chat_id.startswith('whatsapp') or user.cohort < 0 or user.cohort > 20: continue logger.info(f'sending pre sign off to {user.chat_id}') try: _send_message_to_chat_id( update,context,user.chat_id,[sign_off] ) n = n + 1 except: logger.warning(f'Error sending pre sign off to {user.chat_id}') if users.count() > 0: send_text_reply( f"Ok. Successfully sent pre sign off to {n} of {users.count()} users.", update) else: send_text_reply( f"Unable to find any users to send pre sign off message", update)
def _handle_echo(update, context): intent = get_intent(update.message.text) if intent == Intent.UNKNOWN or (int(intent) < 1 or int(intent) > 10): if settings.HINDI: send_text_reply( "मुझे खेद है कि मुझे यह समझ में नहीं आया। यह 1 से 10 के बीच एक भी अंक नहीं है। कृपया 1 से 10 के बीच का कोई एक अंक लिखें।", update) else: send_text_reply( "I am sorry I did not understand that. It is not a single digit number between 1 to 10. Please enter one digit between 1 to 10.", update) else: if settings.HINDI: send_text_reply(f'आपने {str(int(intent))} नंबर दर्ज किया है।', update) else: send_text_reply(f'You have said: {str(int(intent))}', update)
def set_cohort_super_state(update, context): # Save the mssage the nurse sent in logger.warning('Set SUPER cohort-state called in GOD mode!') _log_msg(update.message.text, 'GOD', update) # Check syntax of the command try: cmd_parts = update.message.text.split() if len(cmd_parts) != 3: raise Exception() cohort = cmd_parts[1] new_state = cmd_parts[2] except: send_text_reply( "Usage details for GOD mode: /cohortstate <cohort_number> <new_state_name>", update) return # Find all the users whose: # - not a test user # - in the correct cohort users = Database().session.query(User).filter( ((User.test_user == False) & (User.cohort == cohort)) ) for user in users: # set the state for the user! sm = beneficiary_bot.get_sm_from_track(user.track) try: state_id = sm.get_state_id_from_state_name(new_state) except ValueError: send_text_reply( f"for GOD mode: /cohortstate <cohort_number> <new_state_name>\n'{new_state}' not recognized as a valid state.", update) return False user.current_state = state_id user.current_state_name = new_state msgs, imgs, _, _, _ = sm.get_msg_and_next_state( new_state, user.child_gender) beneficiary_bot.fetch_user_data(user.chat_id, context) msgs, imgs = beneficiary_bot.replace_custom_message(msgs, imgs, context) _send_message_to_chat_id( update, context, user.chat_id, msgs) _send_images_to_chat_id( update, context, user.chat_id, imgs) # Save back to DB Database().commit() # Tell the nurse and check the queue send_text_reply( f"Ok. State successfully set to {new_state} and message sent to {users.count()} users in cohort {cohort}.", update)
def confirm_name(update, context): _log_msg(update.message.text, 'user', update, state='registration') intent = get_intent(update.message.text) if intent == Intent.YES: return _save_name(update, context, update.message.from_user.first_name) elif intent == Intent.NO: if settings.HINDI: send_text_reply( 'ठीक है, कोई बात नहीं। आप मुझसे खुद को क्या बुलवाना पसंद करेंगी (बस एक पहला नाम ठीक है)?', update, state='registration_1b') else: send_text_reply( 'Ok, no problem. What would you like me to call you (just a first name is fine)?', update, state='registration_1b') return ASK_NAME if settings.HINDI: send_text_reply( f"मुझे वह सही से समझ नहीं आया। कृपया 'हां' या 'नहीं' के साथ जवाब दें। क्या मैं आपको {update.message.from_user.first_name} कह कर आपसे बात कर सकती हूँ?", update, state='registration_1x') else: send_text_reply( f"I didn't quite get that. Please respond with 'yes' or 'no'. Can I call you {update.message.from_user.first_name}?", update, state='registration_1x') return CONFIRM_NAME
def save_child_gender(update, context): _log_msg(update.message.text, 'user', update, state='registration_3.5') intent = get_intent(update.message.text) if intent == Intent.ONE: context.user_data['child_gender'] = 'F' elif intent == Intent.TWO: context.user_data['child_gender'] = 'M' else: if settings.HINDI: send_text_reply( f"मुझे वह सही से समझ नहीं आया। कृपया '1' या '2' के साथ जवाब दें। आपके बच्चे का लिंग क्या है?\n1) लड़की\n2) लड़का", update, state='registration_3.5x') else: send_text_reply( f"I didn't quite get that. Please respond with '1' or '2'. What is the gender of your child?\n1) Girl\n2) Boy?", update, state='registration_3.5x') return ASK_CHILD_GENDER if settings.HINDI: send_text_reply( f'{context.user_data["child_name"]} की जन्म की तारिख कब की है? कृपया उस संख्या को इस प्रारूप में लिखें: YYYY-MM-DD (साल-महीना-महीने का दिन)', update, state='registration_3.5') else: send_text_reply( f'What is the birthday for {context.user_data["child_name"]}? Please enter in this format: YYYY-MM-DD', update, state='registration_3.5') return ASK_CHILD_BIRTHDAY
def send_vhnd_reminder(update, context): logger.warning('Send VHND reminder called in GOD mode!') _log_msg(update.message.text, 'GOD', update) # Check syntax try: cmd_parts = update.message.text.split() if len(cmd_parts) != 3: logger.warning('Send VHND reminder: wrong number of args') raise Exception() awc_id = cmd_parts[1] date = cmd_parts[2] if len(awc_id) != 11 or date_re.match(date) is None: logger.warning( f'Send VHND reminder: PROBLEM with arguments AWC chars:{len(awc_id)}') raise Exception() except: send_text_reply( 'Usage details for VHND: /vhnd <awc_id> <DD-MM-YYYY>', update) return users = Database().session.query(User).filter_by(awc_code=awc_id) logger.warning(f'Found {users.count()} users for AWC code {awc_id}') for user in users: if settings.HINDI: msg = f'नमस्ते [mother name]! आपके क्षेत्र में टीकाकरण दिवस {date} को हो रहा है । अपने बच्चे [child name] के साथ अपने आंगनवाड़ी केंद्र जाना ना भूलें!' else: msg = f'Hello [mother name]! The VHSND in your area is happening on {date}. Make sure to go to your AWC with [child name]!' logger.info(f'sending {msg} to {user.chat_id}') _send_message_to_chat_id( update, context, user.chat_id, [msg] ) if users.count() > 0: send_text_reply( f"Ok. Successfully sent VHND reminders to {users.count()} users.", update) else: send_text_reply( f"Unable to find any users with AWC code {awc_id}", update)
def cancel(update, context): _log_msg(update.message.text, 'user', update, state='registration_cancel') send_text_reply('cancel called, ending registration flow', update, state='registration_cancel') return ConversationHandler.END
def ask_child_birthday(update, context): _log_msg(update.message.text, 'user', update, state='registration_4') # No future birthdays and no one older than 1 year if ((datetime.utcnow() - datetime.strptime(update.message.text, '%Y-%m-%d')).days <= 0 or (datetime.utcnow() - datetime.strptime(update.message.text, '%Y-%m-%d')).days >= 365): return wrong_child_birthday(update, context) # Determine the track based on 5 months elif (datetime.utcnow() - datetime.strptime(update.message.text, '%Y-%m-%d')).days >= 150: context.user_data['track'] = 12 if settings.HINDI: send_text_reply('ठीक है, 6-12 महीने।', update, state='registration_4') else: send_text_reply('Ok, 6-12 months.', update, state='registration_4') else: context.user_data['track'] = 6 if settings.HINDI: send_text_reply('ठीक है, 0-6 महीने।', update, state='registration_4') else: send_text_reply('Ok, 0-6 months.', update, state='registration_4') # Save after the error checking and track determination above context.user_data['child_birthday'] = update.message.text if settings.HINDI: send_text_reply( f'समझ गयी। आपका फोन नंबर क्या है? कृपया उसे निम्न प्रारूप में दर्ज करें: + 91dddddddddd, जहां प्रत्येक d एक संख्या है।', update, state='registration_4') else: send_text_reply( f'Got it. What is your phone number? Please enter it in the following format: +91dddddddddd, where each d is a number', update, state='registration_4') return PHONE_NUMBER