Create a webhook endpoint function
Set up an HTTPS endpoint function that can accept webhook requests with a POST method.
Set up your endpoint function so that it:
-
Handles POST requests with a JSON payload consisting of an event object.
-
Quickly returns a successful status code (2xx) prior to any complex logic that could cause a timeout. For example, you must return a 200 response before sending a Slack notification.
Example endpoint
This code snippet is a webhook function configured to check that the event type was received, to handle the event, and return a 200 response.
- PHP
- Python
- Ruby
<?php
// The following example uses PHP to verify a webhook request:
// The freispace webhook secret, viewable from the Webhook details page. In a production environment, set the secret as an environment variable to prevent exposing it in code.
define('FREISPACE_SECRET', 'webhook_secret_key');
// Get the raw POST data
$data = file_get_contents('php://input');
// Get the HMAC signature from the request header
$signature_header = $_SERVER['HTTP_X_FREISPACE_SIGNATURE'];
// Return if the signature header is missing
if (!$signature_header) {
http_response_code(400);
echo json_encode(['message' => 'Missing signature']);
exit();
}
// Compute the HMAC signature of the request payload
$computed_signature = hash_hmac('sha256', $data, FREISPACE_SECRET);
// Verify the computed signature with the signature in the request header
if (!hash_equals($computed_signature, $signature_header)) {
http_response_code(403);
echo json_encode(['message' => 'Invalid signature']);
exit();
}
http_response_code(200);
echo json_encode(['message' => 'Webhook processed successfully']);
// Process the webhook payload
$payload = json_decode($data, true);
?>
# The following example uses Python and the Flask framework to verify a webhook request.
# Ensure that you have Flask installed in your environment using pip install Flask before running the above code.
import hashlib
import hmac
from flask import Flask, request, jsonify
app = Flask(__name__)
# The freispace webhook secret, viewable from the Webhook details page.
# The FREISPACE_SECRET should be stored securely and must never be exposed.
FREISPACE_SECRET = b'webhook_secret_key'
@app.route('/webhook', methods=['POST'])
def handle_webhook():
# Get the HMAC signature from the request header
signature_header = request.headers.get('X-Freispace-Signature')
# Check if the signature header is missing
if not signature_header:
return jsonify({'message': 'Missing signature'}), 400
# Compute the HMAC signature of the request payload
signature = hmac.new(FREISPACE_SECRET, request.data, hashlib.sha256).hexdigest()
# Verify the computed signature with the signature in the request header
# We use hmac.compare_digest instead of a simple comparison (==) because it provides protection against timing attacks.
if not hmac.compare_digest(signature, signature_header):
return jsonify({'message': 'Invalid signature'}), 403
# Process the webhook payload
# Do your logic here
payload = request.json
print(payload)
return jsonify({'message': 'Webhook processed successfully'}), 200
if __name__ == '__main__':
app.run()
# The following example uses Ruby to verify a webhook request.
require 'sinatra'
require 'openssl'
require 'json'
FREISPACE_SECRET = 'webhook_secret_key'
post '/webhook' do
request_body = request.body.read
# Get the HMAC signature from the request header
signature_header = request.env['HTTP_X_FREISPACE_SIGNATURE']
# Return if the signature header is missing
halt 400, { message: 'Missing signature' }.to_json unless signature_header
# Compute the HMAC signature of the request payload
digest = OpenSSL::Digest.new('sha256')
computed_signature = OpenSSL::HMAC.hexdigest(digest, FREISPACE_SECRET, request_body)
# Verify the computed signature with the signature in the request header
halt 403, { message: 'Invalid signature' }.to_json unless Rack::Utils.secure_compare(computed_signature, signature_header)
# Process the webhook payload
payload = JSON.parse(request_body)
puts payload
{ message: 'Webhook processed successfully' }.to_json
end