# Webhooks

Wenn ein Event ausgelöst wird, wird die URL unter `target_url` mit einem `POST` aufgerufen und die Daten des Kontaktes bzw. des Objektes mit übergeben.

Bei `client_updated` und `property_updated` wird zusätzlich der Parameter `changed_attributes` übergeben, damit man auf Aktualisierungen von bestimmten Feldern reagieren kann. Beispielsweise will man in seiner eigenen App eine Aktion ausführen, sobald sich der Preis eines Objektes ändert, und nicht bei jedem Update eines Objektes.

**Mögliche Events:**

1. `client_created`
2. `client_updated` (wird auch beim Löschen gefeuert)
3. `property_created`
4. `property_updated` (wird auch beim Löschen gefeuert)
5. `task_created`
6. `task_updated`&#x20;
7. `task_deleted`
8. `client_property_created`
9. `client_property_updated`
10. `client_property_deleted`
11. `project_created`
12. `project_updated`
13. `document_created`
14. `document_updated`
15. `document_deleted`
16. `saved_query_created`
17. `saved_query_updated`
18. `saved_query_deleted`

## Hook erstellen

<mark style="color:green;">`POST`</mark> `https://api.propstack.de/v1/hooks`

#### Query Parameters

| Name        | Type   | Description                                                          |
| ----------- | ------ | -------------------------------------------------------------------- |
| target\_url | string | Die URL, die aufgerufen soll, wenn der Hook ausgelöst wird           |
| event       | string | Das Ereignis, worauf man hören möchte. Siehe oben für mögliche Werte |

{% tabs %}
{% tab title="200 ID des erstellten Hooks" %}

```javascript
{
    "id": 123
}
```

{% endtab %}
{% endtabs %}

## Hooks aufrufen

<mark style="color:blue;">`GET`</mark> `https://api.propstack.de/v1/hooks`

{% tabs %}
{% tab title="200 " %}

```javascript
{
    "hooks": [
        {
            "id": 10,
            "event": "CLIENT_CREATED",
            "target_url": "https://propstack-immobilien.de/ps-hook"
        }
    ]
}
```

{% endtab %}
{% endtabs %}

## Hook löschen

<mark style="color:red;">`DELETE`</mark> `https://api.propstack.de/v1/hooks/:id`

{% tabs %}
{% tab title="200 " %}

```javascript
{
    "ok": true
}
```

{% endtab %}
{% endtabs %}

## Verifying Webhooks

Verifying webhooks is crucial to ensure the authenticity of the incoming requests and confirm that the data originates from Propstack. To enhance security, we have implemented HMAC (Hash-based Message Authentication Code) verification. This allows developers to confirm that requests come from a genuine source.

When creating a new webhook in the Web UI, there is a field called "Secret Key". Adding a secret key is optional. If it's not set, then no signature will be sent with the webhook. If you do add a secret key, we use this to generate a signature and pass it as a header called `X-Propstack-Signature`.

Here's a simple JavaScript example showcasing how to verify the HMAC signature from your end:

```javascript
const crypto = require('crypto');

function verifySignature(requestBody, signature, secret) {
  const hash = crypto
    .createHmac('sha256', secret)
    .update(requestBody, 'utf8')
    .digest('hex');

  return hash === signature;
}
```

This function generates a hash using the request body and a shared secret, then compares it to the signature provided to validate the request.

#### Verifying HMAC Signature in PHP (WordPress)

For WordPress developers, verifying the HMAC signature can also be done using PHP as shown below:

```php
function verify_signature($requestBody, $signature, $secret) {
  $hash = hash_hmac('sha256', $requestBody, $secret);
  return hash_equals($hash, $signature);
}

// Usage example within a WordPress context
$requestBody = file_get_contents('php://input');
$providedSignature = $_SERVER['HTTP_X_PROPSTACK_SIGNATURE'];
$secret = 'your_secret_key';

if (verify_signature($requestBody, $providedSignature, $secret)) {
  // The request is verified
} else {
  // The request could not be verified
}
```

This PHP function computes an HMAC hash of the request body using the shared secret and compares it to the incoming signature to ensure authenticity.
