Zendesk plugin in HipChat
I’m finally active again on my blog!
For this first post I wanted to quickly show my little Zendesk plugin for HipChat. Our dev team created a bot in HipChat called R2D2 (yes, we have a lot of imagination!). We create different plugins for that bot (useful… or not) and call each plugin by typing !plugin.
Note that the source of the bot itself is not available for now so you will need to hack my plugin to make it work in your HipChat account (or actually any other service, but HipChat rocks).
I had the idea because, firstly I wanted to fool around with Python for the first time of my life
and the Zendesk API; secondly, because our CEO wanted a quick and easy way to have a view on our support team’s performance. Instead of receiving a long reporting email each day or having to log into Zendesk to check the Reporting section, he can fire up the !zendesk command in HipChat and get the stats in a few seconds.
I plan on adding other functionalities soon like SLAs statistics, average Time To Assign, average Time To Resolve, top performers, …
Demo
Best viewed in fullscreen mode.
Source
#!/usr/bin/env python
__author__ = "Arnaud de Theux"
__web__ = "http://arnaud.detheux.org"
__twitter__ = "@AdeTheux"
"""This is a python script that runs as a plugin on top of our HipChat chat bot. It displays information regarding your Zendesk account. To make it run, just complete the Settings part and your branded spokes URL. Note that some code needs our chat bot to run, you will need to modify the code for it to run without our bot"""
import sys
import os
import httplib2
from urllib import urlopen
import urllib
from xml.dom.minidom import parseString
import re
###Settings. Replace with your own Zendesk credentials and URL. If you don't use the API token (baaad) just put your password
user = 'YOUR_USER_EMAIL_ADDRESS/token'
password = 'YOUR_TOKEN'
zendesk = 'http://ACCOUNT.zendesk.com/' # the / at the end is important!
###Fetches unsolved tickets view and returns only number of tickets
class ZendeskBot(BotPlugin):
@botcmd
def zendesk(self, mess, args):
self.send(mess.getFrom(), "/me is preparing the statistics... ", message_type=mess.getType())
h= httplib2.Http(".cache")
h.add_credentials(user, password)
resp, xml_view_opened = h.request(zendesk+"rules/YOUR_VIEW_ID.xml", "GET", headers={'content-type' : 'application/xml'} )
opened_tickets = re.search('','').replace('','')
dom = parseString(content)
xmlTag = dom.getElementsByTagName('count')[1].toxml()
xmlDataTag=xmlTag.replace('','').replace(' ','')
#2
dom = parseString(content)
xmlTag = dom.getElementsByTagName('name')[2].toxml()
xmlDataName1=xmlTag.replace('','').replace(' ','')
dom = parseString(content)
xmlTag = dom.getElementsByTagName('count')[2].toxml()
xmlDataTag1=xmlTag.replace('','').replace(' ','')
#3
dom = parseString(content)
xmlTag = dom.getElementsByTagName('name')[3].toxml()
xmlDataName2=xmlTag.replace('','').replace(' ','')
dom = parseString(content)
xmlTag = dom.getElementsByTagName('count')[3].toxml()
xmlDataTag2=xmlTag.replace('','').replace(' ','')
#4
dom = parseString(content)
xmlTag = dom.getElementsByTagName('name')[4].toxml()
xmlDataName3=xmlTag.replace('','').replace(' ','')
dom = parseString(content)
xmlTag = dom.getElementsByTagName('count')[4].toxml()
xmlDataTag3=xmlTag.replace('','').replace(' ','')
#5
dom = parseString(content)
xmlTag = dom.getElementsByTagName('name')[5].toxml()
xmlDataName4=xmlTag.replace('','').replace(' ','')
dom = parseString(content)
xmlTag = dom.getElementsByTagName('count')[5].toxml()
xmlDataTag4=xmlTag.replace('','').replace(' ','')
#6
dom = parseString(content)
xmlTag = dom.getElementsByTagName('name')[6].toxml()
xmlDataName5=xmlTag.replace('','').replace(' ','')
dom = parseString(content)
xmlTag = dom.getElementsByTagName('count')[6].toxml()
xmlDataTag5=xmlTag.replace('','').replace(' ','')
#7
dom = parseString(content)
xmlTag = dom.getElementsByTagName('name')[7].toxml()
xmlDataName6=xmlTag.replace('','').replace(' ','')
dom = parseString(content)
xmlTag = dom.getElementsByTagName('count')[7].toxml()
xmlDataTag6=xmlTag.replace('','').replace(' ','')
#8
dom = parseString(content)
xmlTag = dom.getElementsByTagName('name')[8].toxml()
xmlDataName7=xmlTag.replace('','').replace(' ','')
dom = parseString(content)
xmlTag = dom.getElementsByTagName('count')[8].toxml()
xmlDataTag7=xmlTag.replace('','').replace(' ','')
#9
dom = parseString(content)
xmlTag = dom.getElementsByTagName('name')[9].toxml()
xmlDataName8=xmlTag.replace('','').replace(' ','')
dom = parseString(content)
xmlTag = dom.getElementsByTagName('count')[9].toxml()
xmlDataTag8=xmlTag.replace('','').replace(' ','')
#10
dom = parseString(content)
xmlTag = dom.getElementsByTagName('name')[10].toxml()
xmlDataName9=xmlTag.replace('','').replace(' ','')
dom = parseString(content)
xmlTag = dom.getElementsByTagName('count')[10].toxml()
xmlDataTag9=xmlTag.replace('','').replace(' ','')
######### WORK IN PROGRESS #########
###Fetches top performer
#Displays the top performer by stripping of the tags on latest tickets
# h= httplib2.Http(".cache")
# h.add_credentials(user, password)
# resp, xml_view_top_perf = h.request(zendesk+"rules/YOUR_VIEW_ID.xml", "GET", headers={'content-type' : 'application/xml'} )
#
# dom = parseString(xml_view_top_perf)
# xmlTag = dom.getElementsByTagName('assignee-name')[0].toxml()
# xmlDataNameTopPerf=xmlTag.replace(' ','').replace(' ','')
######### WORK IN PROGRESS #########
###Display the ouput
if sum_good_percentage >= 85:
result='There is a %i%% satisfaction rate. Good job!\n' % sum_good_percentage
else:
result='There is a %i%% satisfaction rate. That\'s quite low, you should be ashamed!\n' % sum_good_percentage
if opened_tickets > 1:
result+='There is a total of %s unresolved requests at the moment. Chop chop, go solve them!\n' % opened_tickets
else:
result+='There is a total of %s unresolved request at the moment. Chop chop, go solve it!\n' % opened_tickets
result+='These are the top 10 tags and their occurrences: '+xmlDataName+'('+xmlDataTag+') '+xmlDataName1+'('+xmlDataTag1+') '+xmlDataName2+'('+xmlDataTag2+') '+xmlDataName3+'('+xmlDataTag3+') '+xmlDataName4+'('+xmlDataTag4+') '+xmlDataName5+'('+xmlDataTag5+') '+xmlDataName6+'('+xmlDataTag6+') '+xmlDataName7+'('+xmlDataTag7+') '+xmlDataName8+'('+xmlDataTag8+') '+xmlDataName9+'('+xmlDataTag9+')\n'
# result+='The top performer this week is %s. Give that man a raise!' % xmlDataNameTopPerf
return result
You can find the source on my (empty
) GitHub account.
Enjoy!
Update 12/05/2012
Here is our VP of Engineering showing our bot’s JIRA capabilities @ ABUG-3
Tweet








Very nice