
Webhook Management
It is possible to receive status updates from the system by subscribing to certain events.
To do so add a webhook below.
Verification is required to ensure you own the webhook destination. You can either capture the verification event (via logging etc) and manually execute the URL (within 10 minutes of receipt of the event), or handle the verification event in your code and respond with the verification.
When you add the Webhook and you have no validation in place (e.g. the code just responds to the OPTIONS request with a 200 without setting the required headers (detailed below), the webhook will show status AwaitingManualAction - it will remain in this state for 10 minutes, and if the callback is not acknowledged the webhook will be removed and will no longer be shown in the list.
The HTTP OPTIONS method
The OPTIONS method is commonly used to request information about the communication choices that are available from a target, such as a webhook. In the case of CloudEvents, it serves two purposes:
To protect the sender from pushing messages to an endpoint that has not agreed to receiving notifications.
To allow the receiver (the webhook) to indicate if it approves of the ability to have notifications delivered to it.
For both the sender and receiver, the primary driver is abuse protection. The most common issue this addresses is denial-of-service (DDOS) attacks.
Validating HTTP webhooks
When you attempt to create an event subscription, we make a request to the target using the HTTP OPTIONS method. The primary intent of the request is to ask for permission to send notifications.
It’s important to note that this simple handshake does not replace any forms of authentication or authorization.
Validation request
The validation request contains some of the following important header fields:
WebHook-Request-Origin
. This field identifies the sender and any other systems that act on it’s behalf.WebHook-Request-Callback
. An optional field that provides the webhook with an alternative to grant permission asynchronously, by way of a HTTP callback.WebHook-Request-Rate
. The maximum number of requests per minute that the sender will be sending.
Validation response
The target has two options for allowing the delivery of events:
Reply to the validation request by including the
WebHook-Allowed-Origin
andWebHook-Allowed-Rate
headers fields and their corresponding values.Reply to the validation request without the response headers and grant permission by executing a call to the callback URL. If you are logging the requests you will be able to call this URL manually to complete the validation.
The CloudEvents specification covers this portion in more depth, here.
Sample Code (C#):
[HttpOptions]
public async Task<IActionResult> Options()
{
using (var reader = new StreamReader(Request.Body, Encoding.UTF8))
{
// Retrieve the validation header fields
var webhookRequestOrigin = HttpContext.Request.Headers["WebHook-Request-Origin"].FirstOrDefault();
var webhookRequestCallback = HttpContext.Request.Headers["WebHook-Request-Callback"];
var webhookRequestRate = HttpContext.Request.Headers["WebHook-Request-Rate"];
// Respond with the appropriate origin and allowed rate to
// confirm acceptance of incoming notications
HttpContext.Response.Headers.Add("WebHook-Allowed-Rate", "*");
HttpContext.Response.Headers.Add("WebHook-Allowed-Origin", webhookRequestOrigin);
}
return Ok();
}
Status Events
The contents of the status events is show below (it adheres to CloudEvent v1.0 format specification). The data structure includes the id of the ticket, the organisation it belongs to, and the new and previous statuses of the ticket. The Url field includes a link to the ticket in question which can be fetched via the api.
{
"id": "b7f85cb0-dd9b-4437-81ee-b8c271f8a0b2",
"source": "VMG",
"type": "vMobilityGroup.hire.statusChange.v1",
"data": {
"Id": "VMG-726",
"Organisation": "Test Org",
"NewStatus": "Completed",
"PreviousStatus": "OffHireRequested",
"Url": "https://test.api.vmobilitygroup.beintrepid.co.uk/test/api/v1/hires/VMG-726"
},
"time": "2024-08-28T16:33:47.3815092+00:00",
"specversion": "1.0",
"subject": "organisations/test-org/hires/VMG-726",
"traceparent": "00-deacd7d0806d078fed13aa349a4a87f9-e3c032121d85f93a-00"
}