def send_next_module(update, context, cohort): # Find all the users whose: # - next_module is less than max # - not a test user # - Registration was before cutoff users = Database().session.query(User).filter( (User.test_user == False) & (User.cohort == cohort) & (((User.track == '6') & (User.next_module <= settings.MAX_MODULE_6)) | ((User.track == '12') & (User.next_module <= settings.MAX_MODULE_12))) ) for user in users: # Send out messages to user beneficiary_bot.fetch_user_data(user.chat_id, context) user = _send_next_module_and_log(update, context, user) # Increment next_module user.next_module = user.next_module + 1 # Set 'started' and 'first_msg_date' if needed if not user.started: user.started = True user.first_msg_date = datetime.utcnow() # Save back to DB Database().commit() return users.count()
def _send_message_to_queue(update, context, msgs_txt, imgs=[]): """Send msg_text to the user at the top of the nurse queue This does not update the queue (in case we want to send multiple messages. This will, however, log everything correctly""" escalation = Database().get_nurse_queue_first_pending() beneficiary_bot.fetch_user_data(escalation.chat_src_id, context) for msg_txt in msgs_txt: # Log the message from nurse to the user _log_msg(beneficiary_bot.replace_template(msg_txt, context), 'nurse', update, state=Database().get_state_name_from_chat_id(escalation.chat_src_id), chat_id=str(escalation.chat_src_id)) # And send it context.bot.send_message( escalation.chat_src_id, beneficiary_bot.replace_template(msg_txt, context)) for img in imgs: # Log the image from nurse to the user _log_msg(img, 'nurse', update, state=Database().get_state_name_from_chat_id(escalation.chat_src_id), chat_id=str(escalation.chat_src_id)) # And send it f = open(beneficiary_bot.prepend_img_path(img), 'rb') context.bot.send_photo( escalation.chat_src_id, f) f.close()
def _send_next_module_and_log(update, context, user): # Find state associated with the next_module sm = beneficiary_bot.get_sm_from_track(user.track) next_state_name = sm.get_submodule_state_name(f'1_{user.next_module}_') next_state_id = sm.get_state_id_from_state_name(next_state_name) # Get the content msgs, imgs, _, _, _ = sm.get_msg_and_next_state( next_state_name, user.child_gender) beneficiary_bot.fetch_user_data(user.chat_id, context) msgs, imgs = beneficiary_bot.replace_custom_message(msgs, imgs, context) if str(user.chat_id).startswith('whatsapp:'): # Manually adjust messages to the if int(user.next_module) % 2 == 0: msg_template = WA_TEMPLATE_B weeks_old = (datetime.now() - user.child_birthday).days // 7 msg_template = msg_template.replace('{{1}}', user.first_name) msg_template = msg_template.replace('{{2}}', str(int(weeks_old))) msg_template = msg_template.replace('{{3}}', user.child_name) else: msg_template = WA_TEMPLATE_6 if int(user.track) == 6 else WA_TEMPLATE_12 msg_template = msg_template.replace('{{1}}', user.first_name) # Calculate months based on the WHO standard. This may be off by a couple days, # but that's fine for our purposes. months_old = (datetime.now() - user.child_birthday).days // 30.625 msg_template = msg_template.replace('{{2}}', str(int(months_old))) msgs = [msg_template] imgs = [] # Send the content for msg_txt in msgs: # Log the message from system-new-module to the user _log_msg(beneficiary_bot.replace_template(msg_txt, context), 'system-new-module', update, state=Database().get_state_name_from_chat_id(user.chat_id), chat_id=str(user.chat_id)) # And send it context.bot.send_message( user.chat_id, beneficiary_bot.replace_template(msg_txt, context)) for img in imgs: # Log the image from system-new-module to the user _log_msg(img, 'system-new-module', update, state=Database().get_state_name_from_chat_id(user.chat_id), chat_id=str(user.chat_id)) # And send it f = open(beneficiary_bot.prepend_img_path(img), 'rb') context.bot.send_photo( user.chat_id, f) f.close() user.current_state = next_state_id user.current_state_name = next_state_name return user
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 _send_message_to_chat_id(update, context, chat_id, msgs_txt): """Send msg_text to a specific chat_id from GOD mode.""" beneficiary_bot.fetch_user_data(chat_id, context) for msg_txt in msgs_txt: # Log the message from nurse to the user _log_msg(beneficiary_bot.replace_template(msg_txt, context), 'GOD', update, state=Database().get_state_name_from_chat_id(chat_id), chat_id=str(chat_id)) # And send it context.bot.send_message( chat_id, beneficiary_bot.replace_template(msg_txt, context))
def twilio_msg(): msg_id = request.values.get('SmsMessageSid',None) chat_id = request.values.get('From',None) msg = request.values.get('Body',None) # empty context because we're not using telegram context = FakeContext() update = FakeUpdate(chat_id, msg) beneficiary_bot.fetch_user_data(chat_id,context) if context.user_data['child_name'] == 'NONE': # If this user does not exist, create a user in the DB and set to echo state # 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 new_user = User( chat_id=chat_id, cohort=cohort, current_state='echo', current_state_name='echo', registration_date=datetime.utcnow(), test_user=False ) db.insert(new_user) beneficiary_bot.fetch_user_data(chat_id,context) # if chat_id == settings.NURSE_CHAT_ID_WHATSAPP: # print(f"calling nurse input for {msg}") # # Process nurse commands and such # if msg.startswith('/noreply'): # nurse_bot.skip(update,context) # elif msg.startswith('/state'): # nurse_bot.set_state(update,context) # else: # nurse_bot.process_nurse_input(update,context) # elif chat_id == settings.GOD_MODE_WHATSAPP: # # Handle the GOD mode # print(f"calling GOD-mode input for {msg}") # if msg.startswith('/state'): # nurse_bot.set_super_state(update,context) # elif msg.startswith('/cohortstate'): # nurse_bot.set_cohort_super_state(update,context) # elif msg.startswith('/send_next_modules'): # nurse_bot.send_next_modules(update,context) # else: # # Process normal user commands # print(f"calling process user input for {msg}") # beneficiary_bot.process_user_input(update, context) beneficiary_bot.all_done(update,context) return 'ok'
def _send_images_to_chat_id(update, context, chat_id, imgs): """Send msg_text to a specific chat_id from GOD mode.""" beneficiary_bot.fetch_user_data(chat_id, context) for img in imgs: # Log the message from nurse to the user _log_msg(img, 'GOD', update, state=Database().get_state_name_from_chat_id(chat_id), chat_id=str(chat_id)) # And send it f = open(beneficiary_bot.prepend_img_path(img), 'rb') context.bot.send_photo( chat_id, f) f.close()
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 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)