Build a Webhook with Python
In order to build your webhook faster, we provide a Python micro-framework to let you focus on your webhook functionalities.
Read Webhooks reference first!
Before following this guide, please ensure you have read the introduction of the Webhooks reference first. It will help you understand how it work.
Installation
You can install this framework like any other python packages using pip :
pip install clustaar.webhook
Webhook Basics
Activation in a step
Simply activate the use webhook toggle in the desired step:
Minimal code example
Here is a webhook that will trigger an handler
function each times it receives a conversation.step_reached
event.
from clustaar.webhook import Webhook, events
from clustaar.schemas.models import StepReachedResponse, ConversationSession
def handler(request, response, notification):
session = ConversationSession(values={"name": "John"})
return StepReachedResponse(actions=[], session=session)
app = Webhook()
app.on(events.CONVERSATION_STEP_REACHED, handler)
Return Actions
Most of the time, you will want to return actions. The simplest case being to return actions as they were configured in the step.
from clustaar.webhook import Webhook, events
from clustaar.schemas.models import StepReachedResponse, ConversationSession
def handler(request, response, notification):
session = notification.event.session
actions = notification.event.step.actions # an array of actions
return StepReachedResponse(actions=actions, session=session)
app = Webhook()
app.on(events.CONVERSATION_STEP_REACHED, handler)
And if you want to build your own actions or session, you will have to use clustaar.schemas
:
from clustaar.webhook import Webhook, events
from clustaar.schemas.models import StepReachedResponse, ConversationSession, SendTextAction
def handler(request, response, notification):
session_value = notification.event.session.values.get("key", None) # get a session value
notification.event.session.values["key"] = "data" # update or create a session value
session = ConversationSession(values={"name": "John"}) # or create a new session and erase the previous
text_action = SendTextAction(alternatives=["hello", "bye"])
return StepReachedResponse(actions=[text_action], session=session)
app = Webhook()
app.on(events.CONVERSATION_STEP_REACHED, handler)
Routing
Event
Routing is achieved by specifying an event name to the on()
method while configuring your webhook :
app.on(events.CONVERSATION_STEP_REACHED, handler)
Filters
If you want to add some condition to route events based on the request received you can use filters.
In this example, handler
will receive the requests only when the event is of type events.CONVERSATION_STEP_REACHED
and the value of the JSON key data.step.id
equals "507f191e810c19729de860ea"
:
from clustaar.webhook.filters import JSONKeyEquals
app.on(events.CONVERSATION_STEP_REACHED,
handler,
filters=JSONKeyEquals("data.step.id", "507f191e810c19729de860ea"))
JSONKeyEquals
Validates that a JSON key equals an expected value.
data = {
"user": {
"id": 1
}
}
filter = JSONKeyEquals("user.id", 1)
assert filter(data)
data["user"]["id"] = 2
assert not filter(data)
JSONKeyIn
Validates that a key is present in a defined set of values.
data = {
"user": {
"id": 1
}
}
filter = JSONKeyIn("user.id", [1, 2])
assert filter(data)
data["user"]["id"] = 2
assert filter(data)
data["user"]["id"] = 3
assert not filter(data)
JSONKeyExists
Validates that a JSON key is present.
data = {
"user": {
"id": 1
}
}
filter = JSONKeyExists("user.id")
assert filter(data)
del data["user"]["id"]
assert not filter(data)
StepID
Validates that the data.step.id
matches the expected id.
data = {
"data": {
"step": {
"id": "507f191e810c19729de860ea"
}
}
}
filter = StepID("507f191e810c19729de860ea")
assert filter(data)
del data["data"]["step"]["id"]
assert not filter(data)
If you pass a list of step IDs to the StepID
filter it will validate the the data.step.id
is present in the list.
Security
Request signature
If you want to validate the signature of the requests sent by clustaar, you need to provide a private key.
This private key must be set in your bot's webhook configuration.
app = Webhook(private_key="XXXXXXXXXX")
Authentication
If you want to add some authentication to your application you can pass the HTTP basic authentication credentials that you defined in your webhook configuration.
app = Webhook(auth_username="XXXXXXXXXX", auth_password="YYYYYYYYY")
Updated about 4 years ago