Webex Teams recently released support for Adaptive Cards, which allow the user to interact with a teams user (typically a bot) without leaving the page. This is great for taking quick polls, and also piping data from other applications like help desk, travel and expenses, crm, etc.

I love that Cisco adopted the Microsoft standard for Adaptive Cards instead of trying to create their own unnecessarily. The website, adaptivecards.io has great documentation, and a designer to help get started. There is an author sdk as well, but I find that using a templating system such as Jinja2 does the job without learning anything new.

adaptivecards.io/designer

I teach a class at our companywide conference every year called UC Automation, and I thought what a better way to teach about Buttons and Cards (aka Adaptive Cards) than by using it in the class itself. A month prior to the conference, I sent a poll to everyone that registered so they could pick the topics they want to hear about most.

UC Automation: Drinking From the Firehose

To use Adaptive Cards in Webex Teams, I created an example in ๐ŸPython

First install prerequisites:

pip install requests
pip install webexteamssdk
pip install flask

brew install ngrok
ngrok http 3000

Next

import json
import os
import requests
from webexteamssdk import WebexTeamAPI, ApiError
from flask import Flask, request
app = Flask(__name__)

'''
For prototyping, we use ngrok.
We'll request the tunnel and parse the url to use for a webhook
'''
tunnel = json.loads(
  requests.request('GET', url = 'http://localhost:4040/api/tunnels'
  ).text
)
public_url = tunnel['tunnels'][0]['public_url']

'''
Specify the webex token and roomId to use
'''
token = os.environ['token']
roomId = os.environ['roomId']

'''
Using webexteamssdk but also need requests
for attachment action endpoint which is not in sdk yet!
'''
wbx = WebexTeamsAPI(access_token = token)
headers = {
  'Authorization': 'Bearer ' + token
}

'''
Register webhook to ngrok for attachmentActions
'''
for webhook in wbx.webhooks.list():
  wbx.webhooks.delete(webhook.id)

wbx.webhooks.create(
  name = 'Development - ngrok',
  targetUrl = public_url,
  resource = 'attachmentActions',
  event = 'created'
)

'''
Paste Card from adaptivecards.io/designer to a file named card.json 
'''
attachments = []
attachment = {}
attachment['contentType'] = "application/vnd.microsoft.card.adaptive"
attachment['content'] = json.loads(open('card.json').read())
attachments.append(attachment)

'''
Send Message
'''
wbx.messages.create(
  roomId = roomId, 
  markdown = '.', 
  attachments = attachments
)

'''
Receive Data in Webhook and Request Action Payload
'''
@app.route('/', methods = ['POST'])
def index():
  action = request.json['data']['id']
  results = requests.request('GET',
  headers = headers,
  url = f '{wbx.base_url}attachment/actions/{action}'
)
  print(json.loads(results.text))
  return ('', 200, None)

if __name__ == '__main__':
  app.run(port = 3000, use_reloader = True)

Just like with the messages webhook resource, the payload does not include the data, but rather an action id that is used along with the token to retrieve the data, shown below:

{'created': '2019-11-08T21:47:14.436Z',
 'id': 'asdfasdfasdfasdf',
 'inputs': {
  'comments': 'Hereโ€™s a great idea.  Get a real job!'
 },
 'messageId': 'qwerqwerqwerqwerqwerqwer',
 'personId': 'fghjfghjfghjfghjfghjfghj',
 'roomId': 'vbnmbnmvbnmvbnmvbnmvbnm',
 'type': 'submit'}

For my UC Automation class, I stored the results in AWS. Below is a fun script to gather the results and display them with emojis.

from boto3 import *
table = resource('dynamodb').Table('count')

results = table.get_item(Key={'use': 'uc250'})
results = rd.replace_decimals(results['Item'])
del results['use']
results = list(results.items())

for topic in results:
    chart = ๐Ÿ˜Ž
    for i in range(0, int(topic[1])):
        chart = chart+'๐Ÿ˜Ž '
    print(topic[0]+': '+chart)

$ python collect.py

expressway: ๐Ÿ˜Ž ๐Ÿ˜Ž ๐Ÿ˜Ž ๐Ÿ˜Ž 
guest: ๐Ÿ˜Ž ๐Ÿ˜Ž ๐Ÿ˜Ž ๐Ÿ˜Ž ๐Ÿ˜Ž ๐Ÿ˜Ž ๐Ÿ˜Ž ๐Ÿ˜Ž ๐Ÿ˜Ž ๐Ÿ˜Ž ๐Ÿ˜Ž ๐Ÿ˜Ž ๐Ÿ˜Ž ๐Ÿ˜Ž 
cucm: ๐Ÿ˜Ž ๐Ÿ˜Ž ๐Ÿ˜Ž ๐Ÿ˜Ž ๐Ÿ˜Ž ๐Ÿ˜Ž ๐Ÿ˜Ž 
buttons: ๐Ÿ˜Ž ๐Ÿ˜Ž ๐Ÿ˜Ž ๐Ÿ˜Ž ๐Ÿ˜Ž 
admin: ๐Ÿ˜Ž ๐Ÿ˜Ž ๐Ÿ˜Ž ๐Ÿ˜Ž ๐Ÿ˜Ž ๐Ÿ˜Ž ๐Ÿ˜Ž ๐Ÿ˜Ž ๐Ÿ˜Ž ๐Ÿ˜Ž ๐Ÿ˜Ž ๐Ÿ˜Ž ๐Ÿ˜Ž ๐Ÿ˜Ž ๐Ÿ˜Ž ๐Ÿ˜Ž 
xapi: ๐Ÿ˜Ž ๐Ÿ˜Ž ๐Ÿ˜Ž 
browser: ๐Ÿ˜Ž ๐Ÿ˜Ž 
curri: ๐Ÿ˜Ž ๐Ÿ˜Ž  
cms: ๐Ÿ˜Ž 
meetings: ๐Ÿ˜Ž ๐Ÿ˜Ž ๐Ÿ˜Ž 

With the 2.1 release of Cisco Meeting Server API, passcodeMode and passcodeTimeout was added to the callProfile section. This means the classic Personal Meeting Room behavior of the host and guests dialing the same bridge number and having 5 seconds to enter a host pin before defaulting to guest and entering the meeting. Having the same call in number for host and guests greatly simplifies things IMHO.

Full solution below:

Q: What have you been up to in the last year?

The DevNet Creator award was the start of (and perhaps conduit to) a big 2018 for me. I placed second at Presidioโ€™s yearly โ€œShark Tankโ€ coding contest with a CUCM Chat Ops tool called TACOS. I was asked to make a Proof of Concept for Cisco Live using DNA Center APIs which was featured on the floor of the World of Solutions. Our concept, โ€œHoneycombโ€ was an energy monitoring and analysis tool for cost savings in the datacenter. Also at Live, I was invited to speak on a panel with DevNetโ€™s Susie Wee and Hank Preston on โ€œCareer Pivotsโ€ to discuss my transition from Networking to Code. A month later at our own Presidio conference, I helped plan the โ€œDevOpsโ€ track for Presidio and returned the invitation to have DevNet join us (Susie Wee as keynote, Hank Preston with his โ€œNetDevOpsโ€) and taught a few classes myself. At our conference I was awarded โ€œEngineer of the Yearโ€. For the last few months, I have been working on a cloud contact center project on AWS, which has included a ton of serverless architecture (API gateway, Lambda) and chat bots using Lex, Lambda and Elasticsearch. I also just completed a customer wireless pilot for โ€œCisco DNA Spacesโ€, which I customized to add captured data to an Amazon SNS topic for an emergency notification system. I look forward to returning to Create this year to share more of what Iโ€™ve been up to โ€“ whether you catch my talk on โ€œMore efficient governments through contact center AIโ€, ย join my workshop on โ€œHow to teach an old prog new tricksโ€, or just chat over the campfire with some s-mores!

Q: What are you most proud of in your career?

What makes me most proud of in my career is when I can inspire others. I love it when someone I work with approaches me with a new idea to get my take or to help them execute. Sometimes Iโ€™ve never talked to the person before, but Iโ€™m always happy to help. Being able to inspire your peers is beyond titles or certifications. I hope that sharing the use cases Iโ€™ve found for coding helps others think with APIs in mind to really bring value to the customer! If itโ€™s not in the GUI, look in the API docs โ€“ there is our value as integrators. 

Q: If you werenโ€™t a developer, what would you want to be?

I help my wife sometimes with her lesson plans and really get into it. I think if I werenโ€™t in the field Iโ€™m in (or if it paid what it should) I would be a teacher.

Q: What has surprised you most about DevNet and the DevNet community?

What has surprised me most about DevNet is how much fun they have in doing their job, and in general. They are always posting goofy pictures on Twitter, and  always have witty responses to the questions I ask (which they do often, and in short time). A lot of us work from home most days, so the sense of humor Iโ€™ve encountered and friendships Iโ€™ve made (online and offline) are that much more meaningful.

Q: What new technologies/innovations are you most excited about?

AI and Machine Learning are the most exciting for me. The terms have been around for a while, but the algorithms keep getting better and the data sets keep getting larger, more open and shared. That has led to some pretty scary accuracy.ย  One example of this is indico.io, a product that provides sentiment analysis (among other things). I fed a yearโ€™s worth of conversations from our โ€œPresidio Codesโ€ Webex teams space into the API and was able to sort by who was the Happiest or most Angry. I could run it through a Myers-Briggs test, or check for Political Affiliations. I could see right away how this could be used for IVR queueing, hiring or training exercises, or directed marketing.

Apart from sharing URIs and Patterns between clusters, ILS naturally shares UDS data, including home cluster.

In the example below, only a single _cisco-uds._tcp record can exist due to a shared dns zone, however using feature group templates to control the home cluster setting means the user will be “found” and home cluster information will be relayed with the request so the client finds it’s home.

I was asked to help come up with a Proof of Concept using DNA Center APIs for Cisco Live 2018. After a few days in the sandbox, my group decided on an app that gives granular data on power usage using energy wise along with actionable outcomes.

Along with granular cost analysis per IDF, per switch or per port, there is an included calculator for instant cost-benefit analysis. For instance, it takes 7.85kWh or $0.83/mo to power a Cisco 9971 phone but only 2.52kWh or $0.27 to power a newer, more efficient Cisco 8841 phone. At a cost of $250 per, over the span of 10 years, replacing 1,000 phones save $68,133 in power savings alone!

Since I didn’t think I could sit at my first Cisco Live and work a booth talking about charts all day, I decided to add a little “pizazz”. I made a IP Phone app that enrolls your desk phone to your cell phone as a paired device. Typically energy wise is smart enough to turn off your phones screen after 5PM or on the weekends, but with Meraki Scanning API and a location-aware network, phones (and other devices) can turn off and on as needed. Think of a stadium full of APs – leaving a couple on for probing new users and lighting up more as needed!

Pro Tip: When using Meraki Scanning API at an event like Cisco Live with 30,000 people, you may want to tune the power down on the AP, or be ready to re write the body-parser library to handle more throughput and to clean your laptop hard drive every 30 minutes ๐Ÿ™‚

Camp Create is a part of Cisco’s DevNet Create conference and each year they pick about 30 people in groups of 5 and assign a topic. Think of it like a hackathon with some constraints to work with and a coach to guide you.

Since my wife is a teacher, I decided to pick the Education track, and our app “Roll Call” solved the challenge of both: taking roll, and gathering assignments through Cisco Spark and Cisco Meraki APIs.

Having worked with the Cisco Spark APIs, I took on making a bot that serves as the front end to gather assignments and take roll, but also guided the group around the design to make sure everything came together.

One of our group members did a talk on Microsoft’s Face API, and had the idea to use facial recognition to sign onto the WiFi. To track the user to the classroom, Meraki’s Scanning API sends the Device MAC address to a database that stores only the last 10 minutes, and flags those students as “online”

Once the bones were in place, taking roll and asking for assignments was simple.

Another word I’ve heard buzzing around lately, microservices works to brings cloud and containers a step further and modularizes the application into smaller function-specific mini applications that work together through APIs. With this approach, the elasticity of the cloud is tunedย to the needs of the subscribers, and the business only pays for the network and compute resources they need on a more granular level. The early adopters at this point are the usual suspects: Airbnb, Uber and Netflix.

โ€œthe microservice architectural style is an approach to developing a single application as a suite of small services, each running in its own process and communicating with lightweight mechanisms, often an HTTP resource API.โ€

Principals of Microservices (PPT)

Cisco’s APIC-EM, or Application Policy Infrastructure Controller Enterprise Module is an OpenDayLight based SDN (Software Defined Network) controller. You could also possibly call it Cisco’s attempt to Merakify the Enterprise. On the bright side, it’s a free virtual appliance and no license is required.

One of the biggest features of APIC-EM is called Network Plug and Play

At a high level, the Cisco switch or router talks to the APIC-EM to streamline workflows and automate deployments. Switches and routers, known as agents discover the controller using any of the following mechanisms in order:

dhcp option 43 or dns (below), usb key, cloud discovery (currently beta), or the smartphone app.

DHCP

option 43 ascii "5A1N;B2;K4;I172.19.45.222;J80"

The option 43 string has the following components, delimited by semicolons:

  • 5A1N;โ€”Specifies the DHCP suboption for Plug and Play, active operation, version 1, no debug information. It is not necessary to change this part of the string.
  • B2;โ€”IP address type:
    • B1 = hostname
    • B2 = IPv4 (default)
  • Ixxx.xxx.xxx.xxx ;โ€”IP address or hostname of the APIC-EM controller (following a capital letter i). In this example, the IP address is 172.19.45.222.
  • Jxxxx โ€”Port number to use to connect to the APIC-EM controller. In this example, the port number is 80. The default is port 80 for HTTP and port 443 for HTTPS.
  • K4;โ€”Transport protocol to be used between the Cisco Plug and Play IOS Agent and the server:
    • K4 = HTTP (default)
    • K5 = HTTPS

DNS

APIC-EM: pnpserver.<customerdomain>.com
NTP Server: pnpntpserver.<customerdomain>.com

The DHCP pool will need to either be on vlan 1, or you’ll need to specify a staging vlan on the upstream switch:

pnp startup-vlan 55

That brings me to another caveat of of Plug and Play is that the firmware needs to be supported, and may not match the shipping version of the hardware!

Another feature of APIC-EM is called Easy QoS

I actually really like this use-case for network programmability. It’s important for the policies to match end-to-end in QoS, so being able to roll out policies and get insights into your policy-maps holistically is kind of a big deal.

APIC-EM documentation gives the concept of Northbound, which is the REST API you can use for custom applications, and Southbound in which APIC-EM talks to hardware using SNMP and CLI. Cisco states “future APIC-EM releases will leverage other southbound technology such as NetConf as they become available”.

I found some Postman collections from CiscoDevNet’s Github page here. Postman collections are a great way to learn by doing.

APIC-EM Firmware Compatibility

Official Getting Started Guide

When you change your dogs food, they get sick all over the place, they just can’t stomach change. As an IT professional, the dog food we know and love changes frequently.. The technology you spent all that time learning about last year is obsolete.

Donโ€™t get mad, adapt! As a collaboration engineer, my title didn’t exist 20 years ago. During the TDM to VoIP migration, analog teleco guys were forced to adapt or find new work. When virtualization came on the map, the ability for one person to manage hundreds of servers meant that the early adopters got a new title and quite possibly a pay raise, while the ones late to the game found themselves no longer needed.

This blog is adapting, too. Let me throw out a few buzzwords: API, IoT, REST. Knowing what they mean and why they are important might save you from being the next casualty of change. It’s about asking more from technology. People don’t expect their GPS to just give them directions anymore. They want voice navigation with social networking that tells you where the cops are hiding, and they want it to predict when you’re leaving to go to work and tell you how to traffic is. From a development perspective, the GPS apps with the most APIs get the most love, and almost everything is OPEN, meaning you or I could “tap” into that technology, helping both parties.

I recently gave a presentation on coding along with the CTO of the company, Vinu Thomas. One of the points he made that really stuck was this: try to automate your own job. If you’re smart enough to do that, I promise you’ll be just fine.

I started asking during phone migrations: why do I have to tell the router what the new phone’s mac address is, if the switch already knows? Why can’t the switch and the router work this out between themselves ? Why do call center agents have to login to their phone every day if they also login to their computers ? I think we’re almost there, if not already. Both of these use cases: extension mobility and ios-xe have APIs. So do yourself a favor, hang in there, and learn Python.. or Ruby or my favorite: Node.js