GithubHelp home page GithubHelp logo

team-telnyx / demo-appointment-reminders-python Goto Github PK

View Code? Open in Web Editor NEW
1.0 9.0 0.0 6 KB

Meeting scheduler via a Flask application

Home Page: https://developers.telnyx.com/docs/v2/messaging

Python 53.81% HTML 46.19%

demo-appointment-reminders-python's Introduction

Appointment Reminder

Environment setup

To setup our environment, we’re going to install the appropriate packages into a new virtualenv. Virtualenvs allow us to keep Python dependencies independent from project to project.

virtualenv --no-site-packages .scheduler_env
. .scheduler_env/bin/activate
pip install telnyx, Flask, celery, redis

There are a few tools we are going to employ apart from the Telnyx Python Library: Flask allows us to setup a simple HTTP server, Celery will let us schedule meeting reminders for the future, and Redis serves as the backend for Celery.

Configuration

Create a config.cfg file in your project directory. Flask will load this at startup. First, head into the Telnyx Portal, provision an SMS enabled number and Messaging Profile, and create an API Key. Then add those to the config file.

API_KEY='YOUR_API_KEY'
FROM_NUMBER='YOUR_TELNYX_NUMBER'

Note: This file contains a secret key, it should not be committed to source control.

We’ll also place Flask in debug mode and assume all numbers are in the U.S.

DEBUG=True
COUNTRY_CODE='+1'

Server Initialization

The first piece of our application sets up the Telnyx library, Flask, and Celery.

app = Flask(__name__)
app.secret_key = uuid.uuid4()
app.config.from_pyfile('config_file.cfg')
celery = Celery('schedule_meeting_server', broker='redis://localhost:6379')

telnyx.api_key = app.config['API_KEY']

Collect User Input

Create a simple HTML form which collects the meeting date, time, customer name, and phone number. The full HTML source can be found in our GitHub repo, and we’ll serve it with the following Flask route: @app.route('/', methods=['GET', 'POST']).

Implement the SMS Notification

Create a simple function that sends an SMS message parameterized on the destination number and message. The decorator @celery.task allows us to schedule this function to run in the future.

@celery.task
def send_reminder(to, message):
    telnyx.Message.create(
        to=to,
        from_=app.config['FROM_NUMBER'],
        text=message
    )

Note: from is a reserved word in Python. The Telnyx Python Library adds an underscore character to any parameter that would conflict with a reserved keyword.

Parse User Input and Schedule the Message

Setup our route which will handle both GET and POST requests.

@app.route('/', methods=['GET', 'POST'])
def schedule_meeting():
    if request.method == "POST":
        # ...
    return render_template('index.html')

Now, within the conditional, first parse the user date/time input.

meeting_date = datetime.strptime(request.form['meeting_date'], '%Y-%m-%d')
meeting_time = datetime.strptime(request.form['meeting_time'], '%H:%M').time()
meeting_datetime = datetime.combine(meeting_date, meeting_time)

Next, only allow meetings to be scheduled that are three hours and five minutes in the future or later.

now = datetime.now()
if meeting_datetime - timedelta(hours=3, minutes=5) < now:
    flash('Appointment time must be at least 3:05 hours from now')
    return render_template('index.html')

Then, compute the reminder time and message, and schedule the reminder.

Remind the User

Remond the user 3 hours before the meeting.

reminder_datetime = meeting_datetime - timedelta(hours=3)

message = "{customer_name}, you have a meeting scheduled for {meeting_time}".format(customer_name=request.form['customer_name'], meeting_time=str(meeting_datetime))
to = "{country_code}{phone}".format(country_code=app.config['COUNTRY_CODE'], phone=request.form['phone'])

send_reminder.apply_async([to, message], eta=reminder_datetime)

Finally, render the success template.

return render_template('success.html',
                       name=request.form['customer_name'],
                       meeting_name=request.form['meeting_name'],
                       phone=request.form['phone'],
                       meeting_datetime=str(meeting_datetime))

And at the end of the file, start the server.

if __name__ == '__main__':
    app.run(port=5010)

Running the Project

Make sure redis is running in the background, and then start the Celery task and Python server. Assuming your code is in schedule_meeting_server.py.

celery -A schedule_meeting_server.celery worker
python schedule_meeting_server.py

demo-appointment-reminders-python's People

Contributors

arunkumar-telnyx avatar eoghantelnyx avatar jgordley avatar

Stargazers

 avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

demo-appointment-reminders-python's Issues

TypeError: 'UUID' object is not iterable

(sms.service) delegate@delegate:~/sms.service$ python schedule_meeting_server.py 
 * Serving Flask app 'schedule_meeting_server' (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: on
 * Running on http://127.0.0.1:5010/ (Press CTRL+C to quit)
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 818-602-794
127.0.0.1 - - [24/Aug/2021 21:33:32] "GET / HTTP/1.1" 500 -
Traceback (most recent call last):
  File "/home/delegate/anaconda3/envs/sms.service/lib/python3.9/site-packages/flask/app.py", line 2088, in __call__
    return self.wsgi_app(environ, start_response)
  File "/home/delegate/anaconda3/envs/sms.service/lib/python3.9/site-packages/flask/app.py", line 2073, in wsgi_app
    response = self.handle_exception(e)
  File "/home/delegate/anaconda3/envs/sms.service/lib/python3.9/site-packages/flask/app.py", line 2069, in wsgi_app
    ctx.push()
  File "/home/delegate/anaconda3/envs/sms.service/lib/python3.9/site-packages/flask/ctx.py", line 404, in push
    self.session = session_interface.open_session(self.app, self.request)
  File "/home/delegate/anaconda3/envs/sms.service/lib/python3.9/site-packages/flask/sessions.py", line 353, in open_session
    s = self.get_signing_serializer(app)
  File "/home/delegate/anaconda3/envs/sms.service/lib/python3.9/site-packages/flask/sessions.py", line 343, in get_signing_serializer
    return URLSafeTimedSerializer(
  File "/home/delegate/anaconda3/envs/sms.service/lib/python3.9/site-packages/itsdangerous/serializer.py", line 104, in __init__
    self.secret_keys: _t.List[bytes] = _make_keys_list(secret_key)
  File "/home/delegate/anaconda3/envs/sms.service/lib/python3.9/site-packages/itsdangerous/signer.py", line 64, in _make_keys_list
    return [want_bytes(s) for s in secret_key]
TypeError: 'UUID' object is not iterable
$ conda list |egrep 'telnyx|flask|celery|redis'
celery                    5.1.2              pyhd8ed1ab_0    conda-forge
flask                     2.0.1              pyhd8ed1ab_0    conda-forge
redis                     3.5.3                    pypi_0    pypi
telnyx                    1.4.0              pyhd8ed1ab_0    conda-forge

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.