Handling inbound webhooks
Many services generate webhooks when certain events occur, and you may want to get these webhooks and their data into Quix. As Quix services can be deployed as web services, they can receive inbound webhooks easily. You simply handle the webhook in the required way, perhaps using an existing connector as a guide. For example, the Segment connector handles webhooks from the Segment service in the following way:
from quixstreams import Application
from quixstreams.models.serializers.quix import JSONSerializer, SerializationContext
from flask import Flask, request
from datetime import datetime
from waitress import serve
import os
import json
import hmac
import hashlib
app = Application()
serializer = JSONSerializer()
output_topic = app.topic(os.environ["output"])
producer = app.get_producer()
flask_app = Flask("Sample Webhook")
# this is unauthenticated, anyone could post anything to you!
@flask_app.route("/webhook", methods=['POST'])
def webhook():
# get the shared secret from environment variables
secret = os.environ["shared_secret"]
# convert to a byte array
secret_bytes = bytearray(secret, "utf-8")
# get the signature from the headers
header_sig = request.headers['x-signature']
# compute a hash-based message authentication code (HMAC)
hex_digest = hmac.new(secret_bytes, request.get_data(), hashlib.sha1).hexdigest()
# compare the HMAC to the header signature provided by Segment
if(header_sig != hex_digest):
# if they don't match its no bueno
return "ERROR", 401
with producer:
serialized_value = serializer(
value=request.json, ctx=SerializationContext(topic=output_topic.name)
)
producer.produce(
topic=output_topic.name,
key="sample-webhook",
value=serialized_value
)
return "OK", 200
print("CONNECTED!")
# you can use app.run for dev, but its not secure, stable or particularly efficient
# qx.App.run(debug=True, host="0.0.0.0", port=80)
# use waitress instead for production
serve(flask_app, host='0.0.0.0', port = 80)
Note
The Segment webhooks are signed, but for other services this is not always the case, and this will therefore simplify your webhook code.
When you deploy your service you can configure public access in the Deploy
dialog. You can then obtain the public access URL needed to configure the inbound webhook from the Deploy
dialog or from the service itself.
See also How to deploy a public service for more information.