cisco , cisco spark , microsoft teams , Uncategorised , | 2017/01/19 at 8:47am

Cisco Spark Bots chatting to…. Microsoft Teams?!?

Now, it’s odd for a Microsoft partner to want to integrate these two platforms but given they are both the new kids on the block for collaboration and messaging apps, it raised an interesting point – could we get some kind of ‘clearing house’ going between these two platforms to allow messages, links, and other features sent between the two platforms? Now to be perfectly clear, I am not a developer, and a very very amateur scripter and that would indeed be generous. Disclaimer: there may be much more sensible ways of achieving this and I am sure someone will be able to do a much better job! I also couldn’t find much in the blogosphere about how to do this.

Cisco Spark is also relatively new to the market, despite having been around longer than Microsoft Teams, has only seen limited use in my marketplace (Australia). Spark is the new platform from Cisco that incorporates video products like Cisco TelePresence endpoints, Acano/Cisco Meeting Servers and Cisco Call Manager unified communications platforms. It competes directly with Microsoft products like Teams and Skype for Business. Cisco Spark is hosted by Cisco, but they allow you access to their API to be able to create all sorts of integrations and automate processes.

What I have managed to get working is a simple Cisco Spark bot that sits in a Spark Room and can relay these messages to a Microsoft Teams channel. Thinking out loud, a possible scenario using this type of integration could be cross-organization collaboration, or a large organization that operates globally that might utilize both platforms in different business units that need to collaborate. At this stage, I’ve only could get text working, there is no indication if voice and video calling could be achieved between the two platforms. My next step is to get links and file transmission working. This looks to be possible using markdown when you do a POST into Teams. There also should be no reason you can’t configure a Cisco Spark bot to post into an Office 365 Group too as it uses the same APIs and Webhook structure.

At its core, Microsoft Teams is a web based enterprise messaging application that utilizes concepts like the Office 365 Groups and Azure Active Directory to underpin use of the application. All “Teams” are allied to an Office 365 Public Group or can be configured as a “Private” Team.

There are tonnes of integrations and connectors available for Teams, and these are called “Connectors”

Connectors are available for specific Channels in your Teams. For example, you may want to pull a Twitter feed into your Channel to monitor specific keywords or tweets, or an RSS feed from another application that you want to be able to bring into a Channel for discussion or review. There is only an Incoming Webhook right now, so it looks like using this I can only receive data from an external source, I can’t use an Outgoing Webhook in Teams to send data to an outside platform.

The Connector that I am interested in using is the Incoming Webhook. This allows an external product or platform to be able to send messages into your Channel via the Microsoft Teams Webhook/Connector Card reference.


Each Webhook will have a specific URI that you can conduct a HTTP POST to. This is unique to the Channel that you configure the Webhook for, as you can see above.

Create the Webhook with a relevant name and icon and click Create. After this, you’ll get a URL that you can use for any software that may want to make a HTTP POST into your Channel. This is important for later on, so please record this.


Where does the bot fit in?

The bot is created in Cisco Spark and needs to be added to your Spark Room that you want to monitor. You can sign up for a free Cisco Spark account at as well as sign up for the Spark for Developers site.

Once you’ve signed up for Spark and installed the Spark Desktop Client, or even signed in via the Spark website, create a room. I called mine “New Room” – so exciting.

Once you’ve got a room created, click on the information (i) bar at the top. You’ll get a message like this:


You want to Add Integrations & Bots. This will redirect you to the Cisco Spark Depot, where you can add Integrations and Bots to your Rooms. There are lots of pre-configured bots to use, but we want to create our own. Click on Build your Own. This will take you to the Cisco Spark Developers site. If you click into “My Apps” we can then choose whether to build an app or an integration.


Very importantly on the next page – you get an “Access Token”. This is also called a “Bearer Token” and is specifically for the Bot itself. You’ll also have your own Bearer token that comes with Spark, it’s generated when you first sign up. This is unique and specific to your account.


Next step is to get into the Cisco Developer API. They have a handy interactive webpage which lets you kick off API commands against your Spark tenant from here.

You’ll need to do this by clicking on the API Reference at the side and then click Test Mode to ON. You can see from the output below that I’ve been able to list rooms in my Cisco Spark tenant using Test Mode. The RoomId is particularly important as we will need this when creating the Webhook.


What we need to do is now add our Bot to our room that we want it to monitor. It’s easy to do this from the Cisco Spark client.


Once added, we can then see in our member roster that the Bot has been added to the room.


The bot will listen in the room and respond to Mentions like @TestBot. I’ve decided that when I want to send data to Microsoft Teams, I’ll want to mention my TestBot, append the content I want to send, and TestBot will take care of the rest.

Next, we will create a Webhook in Cisco Spark that will fire whenever a particular phrase or text is uttered in the room. We’re looking for Mentions to @TestBot, but I need to monitor all messages in the channel to work that out. When any messages are written in the Channel, the Webhook will fire a HTTP POST to our ‘clearing house’ to let it know there’s a mention message waiting. The script running on the ‘clearing house’ will then go and retrieve the message, and take action if required.

For the ‘clearing house’ script to run, we need an ability to run the script, somewhere on the Internet, publicly accessible. Ideally, this is located in an Azure or AWS Virtual Machine, and can run 24 hours a day 7 days a week. I’ve used a free-tier EC2 instance from Amazon running Linux, but it could be anywhere (Azure, your own IaaS). We only need the ability to run Python and that is it.

Once you’ve signed up for your instance, say AWS or Azure, you’ll need a DNS name or IP address where you want to send the Cisco Webhook too. It should be along the lines of or in Azure it would be something like You can choose your own, it doesn’t matter.

In the API reference, click on Webhooks, then Create a Webhook. MAKE SURE YOU USE YOUR BOT BEARER CODE! Do not use the one that is generated there for you. That’s your personal Spark bearer code.

It should look something like this:


Key fields here:

Authorization/Bearer Code – I can’t stress this enough, you have to use the bearer code of the bot.

Name – Not important, but should identify what the Webhook does. You could have multiple Webhooks per Room.

TargetURL – This is the URL/IP Address of your Amazon/Azure/IaaS instance – you’ll also need to specific a port. The script can run on any port, so select something unique.

Resource – This should be messages, so it’s only triggering when messages are sent in the Room.

Event – This should be set to created, so it’s only triggering when messages are created in the room, not deleted etc.

Filter – This should be set to RoomId=RoomIdHereLongStringReallyReallyLongString so the Webhook is only applying to that Room.

When you’ve filled in all the correct parts, hit Run. Be careful as RoomId is case sensitive. Once that is done you should have a 204 OK on the right-hand side to say the creation of the Webook was successful.

The next part is how we achieve that with a Python script.

This script is based off some Cisco sample code and a bit of messing around (as stated before I am not a developer and a very very amateur scripter). The VM needs Python installed as well as the Python framework called Itty Bitty. You can download it from

Extract Itty into a directory and then copy the below script into Notepad++. First, make all the changes in the Python script.

You’ll need to supply it your Bot Bearer Token and your Teams Webhook URI that you recorded before (you did record it didn’t you?)

Save it as a .PY file and upload this to your Virtual Machine using WinSCP into the same directory as Itty.

<em>from itty import *</em>
<em>import urllib2</em>
<em>import json</em>
<em> </em>
<em>def sendSparkGET(url):</em>
<em>    request = urllib2.Request(url,</em>
<em>                            headers={"Accept" : "application/json",</em>
<em>                                     "Content-Type":"application/json"})</em>
<em>    request.add_header("Authorization", "Bearer "+botbearer)</em>
<em>    contents = urllib2.urlopen(request).read()</em>
<em>    return contents</em>
<em> </em>
<em>def sendSparkPOST(url, data):</em>
<em>    request = urllib2.Request(url, json.dumps(data),</em>
<em>                            headers={"Accept" : "application/json",</em>
<em>                                     "Content-Type":"application/json"})</em>
<em>    request.add_header("Authorization", "Bearer "+botbearer)</em>
<em>    contents = urllib2.urlopen(request).read()</em>
<em>    return contents</em>
<em>                </em>
<em>def sendTeamPOST(url, data):</em>
<em>    request = urllib2.Request(url, json.dumps(data),</em>
<em>                            headers={"Accept" : "application/json",</em>
<em>                                     "Content-Type":"application/json"})</em>
<em>    contents = urllib2.urlopen(request).read()</em>
<em>    return contents</em>
<em> </em>
<em>def index(request):</em>
<em>    webhook = json.loads(request.body)</em>
<em>    print webhook['data']['id']</em>
<em>    result = sendSparkGET('{0}'.format(webhook['data']['id']))</em>
<em>    result = json.loads(result)</em>
<em>    print result</em>
<em>    personemail = result.get('personEmail', '')</em>
<em>    data = result.get('text', '')</em>
<em>    print "From:" + personemail + " " + "Message: " + data </em>
<em>    msg = "Sending your message to Microsoft Teams"</em>
<em>    if <strong>'</strong>'in result.get('personEmail', '').lower():</em>
<em>                print "Done"</em>
<em>    else:</em>
<em>                                sendSparkPOST("", {"roomId": webhook['data']['roomId'], "text": msg})</em>
<em>                                sendTeamPOST("", {"text": data})</em>
<em>    return "true"</em>
<em>####CHANGE THIS VALUE#####</em>
<em>botbearer = "BotBearerAccessTokenHere"</em>
run_itty(server='wsgiref', host='', port=10001) 


Highlighted values need to be thought about and changed with your particular details.

When you’ve edited all the relevant values, save the .py file on your Virtual machine. Importantly in the script you can see the port that the Itty framework/Python script run on, and that needs to match up with your Webhook that you created in Cisco Spark.

You can kick off the script by typing

Sudo python <> and it should look like:


<em>ubuntu@ip-10-0-0-37:~/itty-master$ sudo python</em>
<em>itty starting up (using wsgiref)...</em>
<em>Listening on</em>
<em>Use Ctrl-C to quit.</em>


Now the Python script is running, you can test that your Cisco Spark Webhook is working.

Try doing a @mention to your bot. It should bring up lines of code in the Python script, receiving a HTTP POST from Cisco Spark.

itty starting up (using wsgiref)…

Listening on…

Use Ctrl-C to quit.

{u’roomType’: u’group’, u’created’: u’2017-01-17T11:48:29.593Z’, u’personId’: u’Y2lzY29zcGFyazovL3VzL1BFT1BMRS9kNWJlODRkYi1kMGEwLTQ1MGYtOWY2ZS03OTk0MmFhZGY2Mjg’, u’text’: u’teamsbot hi there, could you send over the Higgins file please’, u’html’: u'<p><spark-mention data-object-type=”person” data-object-id=”Y2lzY29zcGFyazovL3VzL1BFT1BMRS9jMmI2MTA4MC0xODYyLTQ3ZTItYWE2MS01Y2Y3MWFmZWZiNTg”>teamsbot</spark-mention> hi there, could you send over the Higgins file please</p>’, u’personEmail’: u’, u’mentionedPeople’: [u’Y2lzY29zcGFyazovL3VzL1BFT1BMRS9jMmI2MTA4MC0xODYyLTQ3ZTItYWE2MS01Y2Y3MWFmZWZiNTg’], u’roomId’: u’Y2lzY29zcGFyazovL3VzL1JPT00vZTE0YjEwMDAtZGE1Zi0xMWU2LTkzNjUtYTllZWVhNDYwNGFk’, u’id’: u’Y2lzY29zcGFyazovL3VzL01FU1NBR0UvZGQ0MGEwOTAtZGNhYS0xMWU2LTk1M2YtN2Y2MzQ1MWQ0ZWQ1′}

Message: teamsbot hi there, could you send over the Higgins file please – – [17/Jan/2017 11:48:32] “POST / HTTP/1.1” 200 4


{u’roomType’: u’group’, u’created’: u’2017-01-17T11:48:31.794Z’, u’personId’: u’Y2lzY29zcGFyazovL3VzL1BFT1BMRS9jMmI2MTA4MC0xODYyLTQ3ZTItYWE2MS01Y2Y3MWFmZWZiNTg’, u’text’: u’Sending your message to Microsoft Teams’, u’personEmail’: u’’, u’roomId’: u’Y2lzY29zcGFyazovL3VzL1JPT00vZTE0YjEwMDAtZGE1Zi0xMWU2LTkzNjUtYTllZWVhNDYwNGFk’, u’id’: u’Y2lzY29zcGFyazovL3VzL01FU1NBR0UvZGU5MDc5MjAtZGNhYS0xMWU2LWFhMTYtZGI0Y2NlMTQ4ZWVl’} Message: Sending your message to Microsoft Teams

Done – – [17/Jan/2017 11:48:33] “POST / HTTP/1.1” 200 4


It looks like this in Spark:


And now in Microsoft Teams:


As you can see, building on this functionality could be quite powerful for cross-organisation collaboration. There are use cases I wouldn’t have even thought of!

Next steps for me, or someone more skilled in our Identity & Automation team are:

  • Strip the botname out of the text
  • Logic and markdown of links
  • Work out if files and pictures can be transferred between Spark and Teams?

Anyhow, I hope this was helpful. I found some guides online that weren’t as specific as I need it, so hopefully this will help someone else!