Group scheduling – Control your events participation with Python

8 min read

Running an event with limited capacity? You want people to sign up without the risk of them showing up only to find out the event is fully booked. Group scheduling is the ideal solution to manage event participation, and the Nylas Python SDK makes it possible.

All you need to do is create an event, specify its capacity, and inform potential participants about the available spots for them to join.

Is your system ready?

If you already have the Nylas Python SDK installed and your Python environment configured, feel free to continue with the blog.

If not, I recommend reading the post How to Send Emails with the Nylas Python SDK, where we provide a clear explanation of the basic setup.

What are we going to talk about?

What our application will look like

Before proceeding further, let’s take a look at what our application will look like:

Group participation application with Python. 3 available spots

We have the title, date, and time of the event. Additionally, we can see the number of available spots, and there are fields to enter our name and email address.

Group participation application with Python. Reserving an spot

After pressing submit, you’ll be registered, and a confirmation message will be sent:

Class reserved

Additionally, you’ll receive an invitation in your mailbox:

Invitation for the group schedule class

When registering, it’s crucial to complete all fields. Let’s ensure we have some form validation:

Complete all missing fields

When there are no more available spots, the registration will fail:

No spots lefts in the group scheduling

With a confirmation message:

Notification from group full

Installing the Flask package

As we aim to create a web application, our best option is to use Flask, one of the most popular micro-frameworks in the Python world. To install it, run the following commands:

$ pip3 install Flask
$ pip3 install Flask-session

Also, we need to install an additional package called Ice Cream. This package will help us get a better debug print output.

$ pip3 install icecream

Once installed, we’re ready to go.

Creating an Event Generator

As we need to create the event, we’re going to create a file called EventGenerator.py:

# Load your env variables
from dotenv import load_dotenv
load_dotenv()

# Import your dependencies
from nylas import APIClient
import os
import datetime
from datetime import date
from icecream import ic

# Initialize your Nylas API client
nylas = APIClient(
    os.environ.get("CLIENT_ID"),
    os.environ.get("CLIENT_SECRET"),
    os.environ.get("ACCESS_TOKEN"),
)

# Get today's date
today = date.today()
# Schedule start time for today at
START_TIME = int(
    datetime.datetime(today.year, today.month, today.day, 11, 00, 0).strftime("%s")
)
# Schedule end time for today at
END_TIME = int(
    datetime.datetime(today.year, today.month, today.day, 12, 0, 0).strftime("%s")
)

# Create the event holder
event = nylas.events.create()

# Define the event properties
event.title = "Zumba Class with Nyla"
event.location = "Nylas' Office"
event.when = {"start_time": START_TIME, "end_time": END_TIME}
event.calendar_id = os.environ.get("CALENDAR_ID")
event.capacity = 3

event.save(notify_participants=True)

if event.id:
    print("Event created successfully")
    ic(event)
else:
    print("There was an error creating the event")

We can execute this file by typing the following in the terminal:

$ python3 EventGenerator.py

Here is the output:

Creating an event for our group participation

We must copy the ID of the event as we’ll need it. Open up your .env file and add the following:

CLIENT_ID = "YourClientId"
CLIENT_SECRET = "YourClientSecret"
ACCESS_TOKEN = "YourAccessToken"
CALENDAR_ID = "YourCalendarId"
EVENT_ID = "YourEventId"

Now, let’s check the calendar to ensure that the event was generated successfully:

Class notification for the group participation application

Creating the Group Scheduling project

First, create a folder named GroupScheduling. Inside, create two more folders: templates and static.

Now, create a file named GroupScheduling.py with the following source code:

# Import your dependencies
from flask import Flask, render_template, json, flash, request, redirect, session
from flask_session.__init__ import Session
from nylas import APIClient
import datetime
import os
from datetime import date
from icecream import ic

# Create the app
app = Flask(__name__)
app.secret_key = b"ThisIsASecret"
app.config["SESSION_PERMANENT"] = False
app.config["SESSION_TYPE"] = "filesystem"
Session(app)

# Initialize your Nylas API client
def load_nylas():
    nylas = APIClient(
        os.environ.get("CLIENT_ID"),
        os.environ.get("CLIENT_SECRET"),
        os.environ.get("ACCESS_TOKEN"),
    )
    return nylas


# Read event
def read_event(nylas, id):
    event = nylas.events.get(id)
    return event


# Main page of our web application
@app.route("/", methods=["GET", "POST"])
def index():
    # Connect to Nylas APIs
    nylas = load_nylas()
    # Read the event details
    event = read_event(nylas, os.environ.get("EVENT_ID"))
    # Return how many spaces are left and allow to sign up
    capacity = event["capacity"] - len(event["participants"])
    if capacity < 0:
        capacity = 0    
    
    if request.method == "GET":
        return render_template(
            "GroupIndex.html",
            title=event["title"],
            day=datetime.datetime.fromtimestamp(event.when["start_time"]).strftime(
                "%A %d, %Y"
            ),
            _from=datetime.datetime.fromtimestamp(event.when["start_time"]).strftime(
                "%H:%M %p"
            ),
            _to=datetime.datetime.fromtimestamp(event.when["end_time"]).strftime(
                "%H:%M %p"
            ),
            capacity = capacity,
        )
    else:
        name = request.form["name"]
        email = request.form["email"]
        # Session variables
        session["name"] = name
        session["email"] = email
        # Make sure all fields are filled
        if not name:
            flash("Name is required!")
            return redirect("/")
        elif not email:
            flash("Email is required!")
            return redirect("/")
        else:
            session["name"] = None
            session["email"] = None
            PARTICIPANTS = event["participants"]
            START_TIME = event["when"]["start_time"]
            END_TIME = event["when"]["end_time"]
            participants_list = {"email": email, "name": name}
            # Get participants and add the new one
            PARTICIPANTS.append(participants_list)
            event.capacity = event["capacity"]
            event.when = {"start_time": START_TIME, "end_time": END_TIME}
            event.participants = PARTICIPANTS
            try:
                # Save the event
                event.save(notify_participants=True)
                return render_template(
                    "GroupConfirmation.html",
                    name=name,
                    email=email,
                    title=event["title"],
                )
            except:
                # Event is full
                return render_template(
                    "GroupFull.html", name=name, email=email, title=event["title"]
                )


if __name__ == "__main__":
    app.run()

In the templates folder, we need to create four different files. Let’s start with base.html:

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width, initial-scale=1">
	<script src="https://cdn.tailwindcss.com"></script>
	<title>Zumba Class with Nyla</title>
</head>
<body>
<div id="container">		
  {% with messages = get_flashed_messages() %}
    {% if messages %}
      {% for message in messages %}
      <div class="flash bg-green-300 border-green-600 border-b p-4 m-4 rounded grid place-items-center text-red-600 font-bold">
        {{ message }}
      </div>  
      {% endfor %}
    {% endif %}
  {% endwith %}	
  {% block content %}  
  {% endblock %}
</div>
</body>
</html>

Then GroupIndex.html:

{% extends 'base.html' %}

{% block content %}
<div class="bg-[#315acb] border-green-600 border-b p-4 m-4 rounded grid place-items-center">
<p class="text-6xl text-center">{{title}}</p><br>
<p class="text-4xl text-center">{{day}}</p><br>
<p class="text-4xl text-center">from {{_from}} to {{_to}}</p><br>
<img src="static/Nyla.png">
<br>
<p class="text-2xl text-center">Currently we have <b>{{capacity}}</b> available spots.</p>
<br>
<form method="post">
<label for="name"><b>Name</b></label>
<input type="text" name="name"
          placeholder="Your name"
          value="{% if session.name != None %} {{session.name}} {% endif %}"></input>
<br><br>
<label for="email"><b>Email</b></label>
<input type="email" name="email"
          placeholder="Your email"
          value="{% if session.email != None %} {{session.email}} {% endif %}"></input>
<br><br>          
<button type="submit" class="block bg-blue-500 hover:bg-blue-700 text-white text-lg mx-auto py-2 px-4 rounded-full">Submit</button>
</form>
</div>
{% endblock %}

We need a confirmation page; let’s call it GroupConfirmation.html:

{% extends 'base.html' %}

{% block content %}
<div class="bg-[#315acb] border-green-600 border-b p-4 m-4 rounded grid place-items-center">
	<h1 class="text-3xl">Thanks {{name}} - {{email}}</h1>
	<p class="font-semibold">You have successfully registered for {{title}}</p>
	<p class="font-semibold">You can now go <a href="{{url_for('index')}}" class="text-green-600">back</a></p>
</div>
{% endblock %}

Finally, let’s create GroupFull.html to inform people that the event is full:

{% extends 'base.html' %}

{% block content %}
<div class="bg-[#315acb] border-green-600 border-b p-4 m-4 rounded grid place-items-center">
	<h1 class="text-3xl">Sorry {{name}} - {{email}}</h1>
	<p class="font-semibold">Sadly, there's no space left for you to join {{title}}</p>
	<p class="font-semibold">You can now go <a href="{{url_for('index')}}" class="text-green-600">back</a></p>
</div>
{% endblock %}

The final step is to add an image to the static folder. Here’s the one we’re using:

Nyla picture

Running our Group Scheduling application

To run our application, simply type the following in the terminal window:

$ python3 GroupScheduling.py
Running our group participation application

The application runs on port 5000 of localhost, so open your favourite browser and navigate to the following address:

http://localhost:5000

Control group participation with Python, is a great way to manage our scheduling events.

If you want to learn more about our Calendar APIs, check out the Nylas documentation Calendar API Overview.

What’s Next?

You can sign up for Nylas for free and start building!

Don’t miss the action, join our LiveStream Coding with Nylas:

Related resources

How to block time slots in Outlook and Google calendar with Nylas Calendar API

Key Takeaways Managing calendar availability is essential for professionals, teams, and businesses to stay organized…

How to Solve Webhook Integration Challenges with PubSub Notification Channel

Key Takeaways This article addresses the challenges of webhook integration and introduces the PubSub Notification…

How to Send Emails Using an API

Key Takeaways This post will provide a complete walkthrough for integrating an email API focused…