pythontwiliosmsoutboundinbound

How to capture no response from user in inbound sms with python in twilio to then exit the inbound and then send an outbound sms message?


I am trying to build a reminder application with twilio and I am having trouble with running a timer in the background while twilio's API waits for a response. It seems the code just waits at @app.route("/sms", methods=["POST"]) for a response before any of the code in the confirm_message function is run. What I am trying to do in the long run is to send outbound messages every 24 hours, but after every outbound message, I send an inbound message for the user to reply, but if the user doesn't reply then the outbound message in the send_message function cannot execute. I anyone can help me with this situation, I would appreciate it.

Thanks

from flask import Flask, request
from twilio.twiml.messaging_response import MessagingResponse
from twilio.rest import Client
import time
import os
import signal
from datetime import datetime

#sending inbound message
app = Flask(__name__)
@app.route("/sms", methods=["POST"])
def confirm_message():
    #after user replies it takes the time
    current_time = time.strftime("%H:%M:%S %p")
    while True:
        # if the time is midnight then os.kill will go back to main and the code restarts
        if current_time == "00:00:00 AM":
            os.kill(signal.CTRL_C_EVENT, 0)
        # else it will get the body of the text and if its "OK" then return back to main, otherwise record the time until its midnight
        # and the code restarts
        else:
            body = request.values.get("Body")
            if body == "OK":
                os.kill(signal.CTRL_C_EVENT, 0)
            else:
                current_time = time.strftime("%H:%M:%S %p")

#sending outbound message
def send_message():
    account_sid = str(input()) 
    auth_token = str(input())
    client = Client(account_sid, auth_token) 

    client.messages.create(  
            messaging_service_sid= str(input()), 
            body='Hi, its time to take your vitamins. \n\nReply OK if you have taken vitamins.',      
            to='+##########'
            )
    print ("Message has been sent")


while True:
    #gets the initial time the outbound message is send
    val1 = datetime.now()
    #sends outbound
    send_message()
    #runs inbound
    app.run(debug=False)
    #gets the send time after outbound and inbound message complete
    val2 = datetime.now()
    #takes difference and converts the time into seconds
    difference = (val1 - val2)
    difference_seconds = 86400.0 - (difference.total_seconds())
    #checks to see if the difference is greater than the number of seconds in 24 hours (86400)
    #if the seconds are greater, then keep adding 86400 untill the difference becomes positive
    while difference_seconds <= 0.0:
        difference_seconds += 86400
    
    #start timer
    starttime = time.time()
    totaltime = 0.0

    #timer continues until it reaches the difference number, which will end of sending another outbound at the same time it did yesterday
    while totaltime <= difference_seconds:
        totaltime = round((time.time() - starttime), 2)

Solution

  • There are a few things here that I don't think will work too well. I don't think the main thread is the right place to run a while True: loop to do background things. Also, you should not run your Flask application as part of that loop as that is also a blocking method that won't return until your application is closed.

    I would suggest that you separate your code that sends scheduled messages and that receives the inbound messages. I'm not sure what you're doing with the current_time that you set when you get an inbound message, but that is likely better stored in a database rather than a local variable.

    You might want to start by looking into how to run a background thread in Python.