Exemple #1
0
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()
Exemple #2
0
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()
Exemple #3
0
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
Exemple #4
0
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)
Exemple #5
0
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))
Exemple #6
0
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'
Exemple #7
0
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()
Exemple #8
0
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)
Exemple #9
0
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)