Overview
Meraki offers a flexible way to integrate webhooks with any REST API service. With the addition of custom payload templates, you can shape the webhook body and headers.
Traditionally, the webhook would be sent to some service that would parse the alert information and then call the 3rd party API with the appropriate format. This adds cost and complexity, which we would like to eliminate.
Custom Payload Templates enable the webhook data to be shaped as desired and sent directly to the destination API, without any additional services in between.
Imagine you need to send an event to a 3rd party event logging service. This service's API may not necessarily be designed to receive "webhooks" but essentially it;
Expects to receive a POST to
Copyhttps://someservice.com/api/events
With some body that looks like this
Copy{
"summary": "Access Point when offline",
"severity": "critical",
"details": ".. the details"
}
And authorization headers that look like this
Copy{
"Authorization": "Bearer 00sOmEAuthToKen000"
}
How can we enable Meraki to talk to this service directly?
By creating a webhook that consists of a URL and a custom template, we can directly communicate with the remote API.
The payload template will shape the headers and body of the Meraki webhook using the Liquid template language, allowing access to the alert variables and additional formatting options.
A Meraki webhook consists of an HTTP server configuration and the alert JSON it will deliver. In the following example, we can see the HTTP server is configured for the 3rd party API and we will use a "Malware download detected" event to see the type of data to expect.
Copy{
"name": "Event Logger",
"url": "https://someservice.com/api/events",
"sharedSecret": "secret123123",
"payloadTemplate": {
"payloadTemplateId": "wpt_00003",
"name": "logservice"
}
}
Copy{
"version": "0.1",
"sharedSecret": "secret123123",
"sentAt": "2021-05-11T08:09:00.065513Z",
"networkName": "Main Office",
"networkUrl": "https://../nodes/list",
"alertType": "Malware download detected",
"alertLevel": "warning",
"occurredAt": "2018-02-11T00:00:00.123450Z",
"alertData": {
"eventType": "amp_malware_detected",
"sha256": "..b72e7386efc5582e4",
"disposition": 3
}
}
Using our example 3rd party events API, we can examine how templates are written using the {{variable}}
syntax as placeholders for the Meraki Alert data. The text can be saved as a *.liquid
file for the respective property.
Headers
Copy{
"Authorization":"Bearer {{sharedSecret}}"
}
Copy{
"Authorization":"Bearer secret123123"
}
Body
Copy{
"summary": "{{alertType}}",
"severity": "{{alertLevel}}",
"details": "{{networkUrl}}"
}
Copy{
"summary": "Malware download detected",
"severity": "warning",
"details": "https://../nodes/list"
}
Using Liquid Templates
The Liquid template language provides a number of options to present and transform the data.
For more information and helpful tools, checkout these resources.
Variables
Using variables in the template requires the property name to be wrapped in double curly braces
{{fooBar}}
Copy{
"some_variable":"{{alertType}}"
}
Copy{
"some_variable": "Cable error detected"
}
Child object properties can also be accessed using the {{foo.bar}}
syntax.
Copy{
"port":"{{alertData.portNum}}"
}
Copy{
"port": "3"
}
Meraki Liquid Filters
In addition to the standard Liquid filters, Meraki has provided a few extras for helpful tasks. Use these by appending a pipe and the name of the filter
jsonify
Converts a JSON object into a JSON string.
Hint, if you see [Object object] try using this
alertData | jsonify
Copy{
"alertData":{{alertData | jsonify}}
}
Copy{
"alertData": {
"portNum": 3,
"description": "Gigabit link negotiation failed",
"status": "10 Gbps",
"prevStatus": "100 Gbps",
"portDesc": "Corp Access"
}
}
json_markdown
Converts a JSON object into a markdown friendly view of the keys and values and avoids clashing when nested in other JSON.
Copy{
"alertData":"{{alertData | json_markdown}}"
}
Copy{
"alertData": "\n portNum:3,\n description:Gigabit link negotiation failed,\n status:10 Gbps,\n prevStatus:100 Gbps,\n portDesc:Corp Access"
}
Copy portNum:3,
description:Gigabit link negotiation failed,
status:10 Gbps,
prevStatus:100 Gbps,
portDesc:Corp Access
keys
Returns the keys of an object.
Copy{
"alertData_key_names":"{{alertData | keys | join:","}}"
}
Copy{
"alertData_key_names": "portNum,description,status,prevStatus,portDesc"
}
dig
Child object properties can be accessed using {{foo | dig}}
.
Copy{
"alertData_key_names":"{{alertData | keys | join:","}}",
"can_you_dig_it":"{{alertData | dig:"portNum"}}"
}
```json
{
"alertData_key_names": "portNum,description,status,prevStatus,portDesc",
"can_you_dig_it": "3"
}
Resources
Webhook Payload Builder
A web tool to help build and test Meraki webhook templates. The application is still in early beta, but offers some additional features to create templates.
Postman
- Manage all of the Meraki API webhook related endpoints with this Postman collection.
Webhook Test Receiver
- Webhook.site is a free service that provides a unique URL to test your webhooks with.
JSON Validator
- Ensure you are writing valid JSON using this online utility. https://jsonformatter.curiousconcept.com