Using Webhooks - Rooms, Messages, Memberships and More!


Tuesday, July 19th 2016

Webhooks are nearly universally implemented and loved in APIs of all shapes and sizes, and the Spark API is no exception. While we launched with just an outbound messaging webhook, the advanced webhook expansion reflects a plethora of options (even a genuine firehose for all events) sure to satisfy nearly any need or want!


We’ll do a quick walkthrough of the more common use cases here, just to get you started, and look forward to the wide range of implementations our developer community puts together. Let us know on Twitter @CiscoSparkDev when you've created something cool!


We’ll start with our first (and most likely to be used) messaging webhook. You can send data showing all created messages, all deleted messages, or both. We’ll focus on created messages, as that’s the more common use. Go here.


Which will bring you to a page with these parameters:


It’s fairly straightforward – name is whatever you want to identify this webhook (really only seen when you list all your webhooks via the API), your targetUrl (in this case, a demo link from, the resource (messages, because obviously), and created since we want all the new messages in the room vs all the deleted messages (or both). You can also define a filter – for our purposes, we’ll go with just the roomId, but you can also combo so you only get messages in a specific room from a specific person by adding multiple filters like:


When you hit Run, the sidebar should look like this:


When a new message is posted to the room, you should get the following content at your targetUrl:

{"id":"Y2lzY29zcGFyazovL3VzL1dFQkhPT0svYjI5NTk2NzAtMTIwZi00OT1234567890asdfghjkl","name":"My Messaging Webhook","targetUrl":"","resource":"messages","event":"created","filter":"roomId=Y2lzY29zcGFyazovL3VzL1JPT00vYTRmMzA2ZDAtNDQ3ZC0xMWU2LTk1234567890asdfghjkl","created":"2016-07-08T02:27:52.191Z","data":{"id":"Y2lzY29zcGFyazovL3VzL01FU1NBR0UvYWE2NTllODAtNDRiMy0xM1234567890asdfghjkl","roomId":"Y2lzY29zcGFyazovL3VzL1JPT00vYTRmMzA2ZDAtNDQ3ZC0xMWU2L1234567890asdfghjkl","personId":"Y2lzY29zcGFyazovL3VzL1BFT1BMRS9lM2EyNjA4OC1hNmRiLTQxZ1234567890asdfghjkl","personEmail":"","created":"2016-07-08T02:28:33.000Z"}}


You can probably tell the message is encrypted, and therefore fairly useless at the moment. You’ll need to make a secondary, authorized call back to the API with the messageId (and personId, potentially, if you need that info) in order to retrieve the actual content of the message body. This page discusses that in more detail.


Once you retrieve the message content, you can do a variety of things with it – track commonly used phrases/questions, see which rooms are most active, use trigger words to post back responses via a bot, quite a wide range of possibilities. For the last one, we posted a recent blog about Spark bots that provides a Python example showing how to retrieve the message content and post a message back to a room; check out the blog post for that example.


Next we’ll cover adding a webhook for created rooms – this is particularly useful if you’re running a bot that can create rooms for various purposes, and want to keep track of the rooms that are generated. Back to the developer portal we go, but this time we’ll change the parameters a bit:


Note: the resource is now ‘rooms’, instead of ‘messages’ and we added a new filter – ‘type=direct’ which means we’ll get a notification every time a 1:1 room is created using the defined Bearer token. After you hit Run, the response should look something like this:


When I create a new 1:1 room, the content sent to my webhook will look like this:

{"id":"Y2lzY29zcGFyazovL3VzL1dFQkhPT0svMDIyNmY2MWEtZWRmYi00OT1234567890asdfghjkl","name":"My Rooms Webhook","targetUrl":"","resource":"rooms","event":"created","filter":"type=direct","created":"2016-07-08T03:29:14.877Z","data":{"id":"Y2lzY29zcGFyazovL3VzL1JPT00vMzBjMzNhMjAtNDRiYy0xMWU2LThmN2It1234567890asdfghjkl","type":"direct","isLocked":false,"lastActivity":"2016-07-08T03:29:34.460Z","created":"2016-07-08T03:29:34.402Z"}}


Like the messages, most of that is encrypted, so you’ll need to make an authenticated call back to the API to get the room details; this doc page explains in more detail.


Last we’ll show webhooks for both created and deleted memberships, so you know if someone joined or left a room you’re already in. To start, the webhook for created memberships:


We’re setting the resource to ‘memberships’, leaving the event as ‘created’ like the others, and defining a specific roomId for the filter so we know who joins one particular room. After you hit Run, your response should look like this:


Now once someone joins the room, we’ll get data sent to our targetUrl that looks like this:

{"id":"Y2lzY29zcGFyazovL3VzL1dFQkhPT0svYTNiMTZkMzctNjNlNi00ZDU2L1234567890asdfghjkl","name":"My Membership Webhook","targetUrl":"","resource":"memberships","event":"created","filter":"roomId=Y2lzY29zcGFyazovL3VzL1JPT00vOTczZmQ3MzAtNDRiZC0xMWU1234567890asdfghjkl","created":"2016-07-08T03:42:00.672Z","data":{"id":"Y2lzY29zcGFyazovL3VzL01FTUJFUlNISVAvMmQxYjhiN2YtZWM0Ny00MTk5LTkzYjUtYjQyMjczM2JiMzZlOjk3M2ZkNzMwLTQ0Y1234567890asdfghjkl","roomId":"Y2lzY29zcGFyazovL3VzL1JPT00vOTczZmQ3MzAtNDRiZC0xMWU2L1234567890asdfghjkl","personId":"Y2lzY29zcGFyazovL3VzL1BFT1BMRS8yZDFiOGI3Zi1lYzQ3LTQ1234567890asdfghjkl","personEmail":"","personDisplayName":"Example Person","isModerator":false,"isMonitor":false,"created":"2016-07-08T03:42:57.054Z"}}


You may not need to make any additional callbacks on this one – the personEmail and personDisplayName are both in plain text and may be all you need, along with the date. If you have a bunch of webhooks pointing to the same place, you may need to get the room details to know which room someone joined, but beyond that most of what you need is available in the clear.


To run a webhook on deleted memberships – some leaving or booted out of the room – it’s mostly the same steps as the last example, just set “deleted” as the event value (and make sure you name it something unique for easier review). When you Run that request, the response on the right should look like this:


After someone leaves the room, the JSON sent to the targetUrl will look something like this:

{"id":"Y2lzY29zcGFyazovL3VzL1dFQkhPT0svNWFhNmFmMWQtZDM2Mi001234567890asdfghjkl","name":"Deleted Membership Webhook","targetUrl":"","resource":"memberships","event":"deleted","filter":"roomId=Y2lzY29zcGFyazovL3VzL1JPT00vZThhOTQ3MzAt1234567890asdfghjkl","created":"2016-07-10T16:48:15.995Z","data":{"id":"Y2lzY29zcGFyazovL3VzL01FTUJFUlNISVAvNmE2MmU5Y2EtOGNkMi00NTZkLTlkOWQtOWYzZDE0OWExYjkxOmU4YTk0NzMwLTQ2Ym1234567890asdfghjkl","roomId":"Y2lzY29zcGFyazovL3VzL1JPT00vZThhOTQ3MzA1234567890asdfghjkl","personId":"Y2lzY29zcGFyazovL3VzL1BFT1BMRS82YTYyZTljYS04Y2Q1234567890asdfghjkl","personEmail":"","personDisplayName":"Example Person","isModerator":false,"isMonitor":false,"created":"2016-07-10T16:49:16.325Z"}}


With those examples to get you started, you should be able to add all kinds of functionality to your integrations and applications using the vastly expanded options. Please give them a run and if you have any questions, please don’t hesitate to shoot us an email via!


Justin Dupree, Global Manager, Collaboration API Support