The app works by leveraging the Meraki Dashboard API and Webhooks.
Dashboard API for CMDB Sync
A scheduled job is run to import Meraki data via the API. Once imported, the data is then mapped to the related CMDB tables.
Scheduled Job
SG-Meraki Devices
Runs according to the user defined schedule

Data Source
The job uses a script to obtain the Meraki data.

Use this Postman Collection to easily test the following API endpoints.
Authentication
The app will use the provided read-only Meraki API key to pull all related records associated with it.
Organizations
GET
/organizations
API Response Data
[
{
"id": "2930418",
"name": "Customer 1",
"url": "https://dashboard.meraki.com/o/sdfAd/manage/organization/overview"
},
{
"id": "8768683",
"name": "Customer 2",
"url": "https://dashboard.meraki.com/o/VjjsAd/manage/organization/overview"
}
]
Networks
GET
/organizations/{organizationId}/networks
API Response Data
[
{
"id": "L_123456",
"organizationId": "2930418",
"name": "Long Island Office",
"timeZone": "America/Los_Angeles",
"tags": [ "tag1", "tag2" ],
"productTypes": [
"appliance",
"switch",
"wireless"
],
"enrollmentString": "long-island-office"
}
]
Devices
GET
/organizations/{organizationId}/devices
API Response Data
[
{
"name": "My AP",
"lat": 37.4180951010362,
"lng": -122.098531723022,
"address": "1600 Pennsylvania Ave",
"notes": "My AP's note",
"tags": " recently-added ",
"networkId": "N_24329156",
"serial": "Q234-ABCD-5678",
"model": "MR34",
"mac": "00:11:22:33:44:55",
"lanIp": "1.2.3.4",
"firmware": "wireless-25-14"
}
]
Device Statuses
GET
/organizations/{organizationId}/devices/availabilities
API Response Data
[
{
"mac": "00:11:22:33:44:55",
"name": "My AP",
"network": { "id": "N_24329156" },
"productType": "switch",
"serial": "Q234-ABCD-5678",
"status": "online",
"tags": [ "tag1", "tag2" ]
}
]
Default Device family to CI Class Mapping List
CI classes are the database tables for ServiceNow (for example, cmdb_ci_wap_network, cmdb_ci_ip_router, and cmdb_ci_ip_switch) This table displays the Cisco Meraki default CI classes for each device family. The default CI classes can be modified by the user (Please refer to the troubleshooting guide for instructions on how to edit the mappings). In case of other device families not listed below, the ServiceNow application user needs to either manually create the corresponding CI Classes and attributes/references mapping or use a pre-existing CI class a 'parent' CI class.
| Device Family | Corresponding CI Class |
|---|---|
| Wireless Access Points (MR, CW) | cmdb_ci_wap_network |
| MG, MX, Z3, Z4, C8 | cmdb_ci_netgear |
| MS, C9 | cmdb_ci_ip_switch |
| MV | cmdb_ci_ip_camera |
| MT | cmdb_ci_ot_industrial_sensor |
| Default class if no existing Model to CI Class mapping exist | cmdb_ci_hardware |
Webhooks Alerts for Incident Creation
A scripted service will provide a REST endpoint exposing a URL based upon your instance and configured user account.
Priority of incidents can be defined by adding/modifying records in the Device Alerts lookup table found in the System Policy application menu.
API Resource
API ID: sgmeraki_device_alerts
Path: /api/x_caci_sg_meraki/sgmeraki_device_alerts
Method: POST
API Script Details
SGMerakiSNAlerts
(function process( /*RESTAPIRequest*/ request, /*RESTAPIResponse*/ response) {
// Parse Meraki Alerts Webhook Data
var requestBody = request.body.dataString;
var requestParsed = {};
gs.info('SNAlerts-' + requestBody);
requestParsed = JSON.parse(requestBody);
var merakiAlert = requestParsed;
var grp = gs.getProperty('x_caci_sg_meraki.meraki_alert_group');
var ciId = '';
var ci = new GlideRecord('cmdb_ci');
ci.addQuery('serial_number', requestParsed.deviceSerial);
ci.query();
if (ci.next()) {
ciId = ci.getUniqueValue();
}
var inc = new GlideRecord('incident');
inc.newRecord();
inc.contact_type = 'monitoring';
inc.category = 'Alert';
if (grp != '')
inc.assignment_group = grp;
inc.short_description = requestParsed.alertType;
inc.x_caci_sg_meraki_device_alert = requestParsed.alertType;
inc.description = 'Alert ' + requestParsed.alertType + ' received for device: ' + requestParsed.deviceName + ' SN: ' + requestParsed.deviceSerial + '\n';
var level = 0;
var myString = '';
for (var name in requestParsed) {
if (typeof requestParsed[name] == 'object') {
myString += "\n" + " ".repeat(level * 4) + name + ": ";
var stuff = new SGConnectorMerakiUtils().parseLevel1(requestParsed[name], 1);
myString += stuff;
} else {
myString += "\n" + " ".repeat(level * 4) + name + ": " + requestParsed[name];
}
}
inc.description += myString;
if (ciId != '')
inc.cmdb_ci = ciId;
inc.insert();
})(request, response);