How to locally test your Webhooks using Python

7 min read

In our daily lives, we continuously send and receive emails, create calendar events, update contacts, and more. Webhooks offer an ideal solution for receiving notifications when any of these events occur. With webhooks, you don’t have to constantly request information; instead, you can simply wait for notifications to be delivered to your application. While you typically need an external server to host your webhook-enabled application, the Nylas Python SDK makes it easy to test local webhooks on your machine.

What are we going to talk about?

Ways to test Webhooks

As we’ve seen, we can employ a web server to test our webhooks, as demonstrated using Ruby, Python, and PHP. Additionally, we can test webhooks locally using the Nylas CLI.

In Episode 26 of Coding with Nylas, titled Exploring Nylas’ Webhook Utilities we received a glimpse of using the NodeJS SDK to test webhooks locally.

Now, let’s delve into our main focus: demonstrating how to use another one of our SDKs to test webhooks locally—the Python SDK.

Why test Webhooks locally

Testing anything on our local machine is advantageous because, if something goes wrong, we can quickly address it. Testing on a web server can be more complex, requiring the repetition of a lengthy workflow to implement necessary changes.

By testing locally, we can ensure that everything is functioning correctly before deploying it to an external web server.

What does our application look like?

Typically, we develop web applications using Flask, but this time, we’re opting to create a Desktop application using DearPyGUI.

Locally testing our webhooks with Python

As we can here, we’re going to have the following information available:

  • Id → The message id. This will help us to retrieve the message information.
  • Date → Date and time when the webhook notification gets generated.
  • Email From → Who is sending the message
  • Email To → Who is receiving the message
  • Title → Subject of the message
  • Type → Type of Webhook, created, updated or opened.

But we also have a BarPlot dashboard showing how many emails were sent and how many were received.

Is your system ready?

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

However, if you haven’t done so yet, I recommend checking out the post How to Send Emails with the Nylas Python SDK, where the basic setup is clearly explained.

Installing the DearPyGUI package

The installation process is straightforward. Simply type the following command in our terminal window:

$ pip3 install dearpygui

Creating our webhooks Desktop application

First, create a folder named Local_Webhooks. Inside this folder, create another one named fonts.

Download the Roboto Font Family and move the file Roboto-Regular.ttf into the fonts folder.

Now, let’s create a file named local_webhooks.py in the root folder:

# Import your dependencies
import dearpygui.dearpygui as dpg
from nylas import APIClient
from nylas.services.tunnel import open_webhook_tunnel
from nylas.client.restful_models import Webhook
import os
import datetime
from dotenv import load_dotenv

# Load your env variables
load_dotenv()

# Create the GUI Context
dpg.create_context()

# Register our font and size
with dpg.font_registry():
    default_font = dpg.add_font("fonts/Roboto-Regular.ttf", 20)

# Initialize an instance of the Nylas SDK using the client credentials
nylas = APIClient(
    os.environ.get("CLIENT_ID"),
    os.environ.get("CLIENT_SECRET"),
)

# Initialize an instance of the Nylas SDK using the client credentials
nylas_mail = APIClient(
    os.environ.get("CLIENT_ID"),
    os.environ.get("CLIENT_SECRET"),
    os.environ.get("ACCESS_TOKEN")
)

# Variables to hold our information
webhooks_list = []
sent = [0]
received = [0]

# Main function to run our Webhooks
def run_webhook():
    # When a webhook notification gets triggered
    def on_message(delta):
        # We're only checking for message created or message updated
        if delta["type"] == Webhook.Trigger.MESSAGE_CREATED or 
           delta["type"] == Webhook.Trigger.MESSAGE_UPDATED:
	    # With the id, get the message details
            message = nylas_mail.messages.get(delta["object_data"]["id"])
            # Fill our array variable with all needed information
            webhooks_list.append([delta["object_data"]["id"],
                     datetime.datetime.fromtimestamp(delta["date"]).strftime('%Y-%m-%d %H:%M:%S'),
                     message.from_[0]["email"],message.to[0]["email"],message.subject,delta["type"]])
            # Only for message created
            if delta["type"] == Webhook.Trigger.MESSAGE_CREATED:
		# Determine whether we're are sending or receiving emails
                if message.to[0]["email"] == os.environ.get("EMAIL_ID"):
                    received[0] += 1
                else:
                    sent[0] += 1
            # Update the BarPlot
            dpg.set_value('sent', [[6], sent])
            dpg.set_value('received', [[16], received])
            dpg.fit_axis_data("yaxis_tag")
            # Delete the table in order to recreate it
            dpg.delete_item("table")
            # Specify the table again
            with dpg.table(header_row=True, tag="table", parent="window"):
                dpg.add_table_column(label="Id")
                dpg.add_table_column(label="Date")
                dpg.add_table_column(label="Email From")
                dpg.add_table_column(label="Email To")
                dpg.add_table_column(label="Title")
                dpg.add_table_column(label="Type")
				
		# Read our array and put the information on the table
                for hook in webhooks_list:
                    with dpg.table_row():
                        dpg.add_text(hook[0])
                        dpg.add_text(hook[1])
                        dpg.add_text(hook[2])
                        dpg.add_text(hook[3])
                        dpg.add_text(hook[4])
                        dpg.add_text(hook[5])

    # When the webhooks get connected 
    def on_open(ws):
        print("opened")

    # Do we have any errors? 
    def on_error(ws, err):
        print("Error found")
        print(err)

    # Open the webhook tunnel and wait for incoming notifications 
    open_webhook_tunnel(
        nylas, {"on_message": on_message, "on_open": on_open, "on_error": on_error}
    )

# Create the application window
with dpg.window(label="Webhooks Table", tag="window", 
pos=(0,0), width=1100, height=300, no_resize = True, no_close = True, no_collapse = True):
    # Bind our font, so that we can use it
    dpg.bind_font(default_font)
    # Create the table
    with dpg.table(header_row=True, tag="table"):
        # Define the columns
        dpg.add_table_column(label="Id")
        dpg.add_table_column(label="Date")
        dpg.add_table_column(label="Email From")
        dpg.add_table_column(label="Email To")
        dpg.add_table_column(label="Title")
        dpg.add_table_column(label="Type")

# Create the BarPlot
with dpg.window(label="", width=500, height=300, pos=(300,301), no_title_bar = True):
    with dpg.plot(height=-1, width=-1, no_title = True):
		# Add legend
        dpg.add_plot_legend(location = 1)

        # Define the BarPlot characteristics and initial data 
        dpg.add_plot_axis(dpg.mvXAxis, label="", no_gridlines=True, tag="x_axis",no_tick_labels = True)
        dpg.set_axis_limits(dpg.last_item(), 1, 20)
        dpg.add_plot_axis(dpg.mvYAxis, label="", tag="yaxis_tag")
        dpg.set_axis_limits_auto("yaxis_tag")
        dpg.add_bar_series([6], sent, label="Sent", weight=1, parent="yaxis_tag", tag = "sent")
        dpg.add_bar_series([16], received, label="Received", weight=1, parent="yaxis_tag", tag = "received")
        
# Call the webhook function
run_webhook()
# Define the application viewport
dpg.create_viewport(title='Webhooks Monitor', width=1100, height=600)
# Initialize the application
dpg.setup_dearpygui()
# Display the viewport
dpg.show_viewport()
# Start our application
dpg.start_dearpygui()
# Destroy the context when the application ends
dpg.destroy_context()

Running our Webhooks Desktop application

To execute our script, all we need to do is run it like this:

$ python3 local_webhook.py

What’s next?

Testing local webhooks with Python saves you a lot of time and helps you to prevent errors.

If you want to learn more about Webhooks, go to our documentation.

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…