In customer support, chatbots represent an opportunity to automate simple and repetitive tasks while allowing the support team to focus on resolving more complex customer problems. Zendesk’s recent announcement on the release of Chat Conversations API represent a significant addition to the self-service offering for businesses using Zendesk Chat to support their customers. If you were using Zendesk Chat for support, you have probably waited for this release for a long time.
While the new API comes integrated with a small number of chatbot providers, developing the integration yourself will give you the flexibility o choose from a much larger selection of chatbot vendors and APIs, without being locked in with one vendor.developing the integration yourself will give you flexibilityIn this tutorial I will describe in a few simple steps how one can develop such an integration with one popular chatbot service, IBM Watson Assistant. However, alternative services such as Google’s Dialogflow or Microsoft’s Azure Bot Service, could be easily used instead.

 

Getting started

First here is what you need to get started:

 

  • Zendesk chat account (Premium or Enterprise)
  • Sign up with IBM Bluemix or alternative chatbot service
  • Python3 and packages: requests, websocket-client, watson-developer-cloud

Your chatbot app is configured into your Zendesk Chat account as an additional Agent user. Like any agent, it would need to authenticate before being able to take on and respond to incoming chats from customers. You can either create an additional user for your chatbot or use your own account. The latter is for testing only. Obviously, you don’t want your customers to believe they are chatting to a real person, so make sure you name and introduce the new agent/chatbot accordingly.
Once you have a user, the next step is to configure how the chatbot app will authenticate. Zendesk Chat supports several authentication methods, all based on the OAuth authorization flow. Given that the chatbot is a server-side app, the most appropriate methods are either Password grant or Client credentials grant. Please follow the instructions at this page to setup the OAuth configuration for the chatbot user and implement the flow. What you get in the end is an access token (think of it as a super password) to be used in the next steps.
You’ll also need to sign up and setup your chatbot service of choice. For this tutorial we are using IBM Watson Assistant, but alternatively you can select other chatbot services such as Azure Bot Service from Microsoft or Dialogflow from Google. What I liked about Watson Assistant was that it comes pre-installed with a sample customer service bot that makes it easy to get started. Sign up here for a free account and follow these instructions to configure your workspace. Select the customer service sample workspace to use a predefined chatbot example that can handle simple FAQ type queries such as serving stores opening hours or location.

 

How a chatbot app works in Zendesk Chat

If you think of your chatbot as an app that simulates how a real agent is using the chat platform to handle customer queries, the app flow would look like this:

 

  • app is initializing and authenticates itself to the chatbot service
  • app authenticates to the livechat platform and starts a session by making itself available
  • app is waiting for new messages from visitors
  • when a message is received, send it to the chatbot service (Watson Assistant in this example)
  • receive response from the chatbot service and send it to the visitor

think of your chatbot as an app that simulates how a real agent is using the chat platform to handle customer queries
It is as simple as that! The steps described above are well suited for FAQ types of dialogues but can be enriched to support chatbots with more complex dialog flows where context needs to be maintained for each visitor. We decided to keep this complexity outside the scope of the current tutorial.

 

Initialization and authentication

So let’s start by initializing the app and authenticating the chatbot user. The authentication part is done through HTTP requests, while for the actual conversations we’ll be using a WebSocket connection. As explained here, the Conversations API is based on the GraphQL data query language which gives the developer more flexibility in terms of defining precisely the data an application needs.

 

import requestsimport jsonimport websocket# define the GrapQL mutation query for authenticating an agentauthenticate_query = """mutation { startAgentSession(access_token: "your_chatbo_user_access_token") {   websocket_url   session_id   client_id }}"""# call the REST endpoint to authenticate the agentr = requests.post("https://chat-api.zopim.com/graphql/request",                 params=pFarams, json={"query":authenticate_query})if r.status_code == 200: jret = r.json() # includes the authenticated websocket session details session = jret["data"]["startAgentSession"] print (session["websocket_url"])else: print (str(r.status_code), ", ", r.content)

Running the snippet above will get you the authenticated WebSocket address that will be used next to implement the dialogue with the user. But in the meantime, let’s also initialize the Watson Assistant session:

 

watson_conversation = { "url": "https://gateway.watsonplatform.net/assistant/api", "username": "<your user name>", "password": "<your password>"}from watson_developer_cloud import AssistantV1assistant = AssistantV1(username=watson_conversation["username"],                       password=watson_conversation["password"],                       version='2018-02-16')

 

 

Setting up the chat session

Now that we have the WebSocket address, let’s setup a websocket session and subscribe to incoming chat messages, while setting the status of the authenticated chatbot agent to “online” in order to be able to receive the chats.

 

# define the message subscription queryMESSAGE_SUBSCRIPTION = 123messageSubscriptionQuery = { "payload": {   "query": """subscription {     message {       node {         id         content         channel {           id         }         from {           __typename           display_name         }       }     }   }   """ }, "type": 'request', "id": MESSAGE_SUBSCRIPTION}# define the update agent status queryUPDATE_AGENT_STATUS  = 124updateAgentStatusQuery = { "payload": {   "query": """mutation {     updateAgentStatus(status: ONLINE) {       node {         id       }     }   }    """ }, "type": 'request', "id": UPDATE_AGENT_STATUS}# initialize the websocket sessionws = websocket.WebSocket()ws.connect(session["websocket_url"])# subscribe to receive messagesws.send(json.dumps(messageSubscriptionQuery))response = ws.recv()print(response)rJson = json.loads(response)# we will need the subscription id in the next stepsubscription_id = rJson["payload"]["data"]["subscription_id"]# set the chatbot agent status to 'online"ws.send(json.dumps(updateAgentStatusQuery))response = ws.recv()print (response)

 

Sending and receiving messages

Now it’s time to start receiving chat messages:

 

while True:# receive websocket messagesmessage = ws.recv()data = json.loads(message)# make sure we listen to chat messages from the our subscriptionif "sig" in data and data["sig"] == 'DATA' and \ 
            data["subscription_id"] == subscription_id and \
            "payload" in data and "data" in data["payload"]:# the chat message structure will include the message string but 
# also sender details chatMessage = data["payload"]["data"]["message"]["node"] sender = chatMessage["from"] # make sure the message is from a visitor if sender["__typename"] == "Visitor":   # we have to do something with the message, let's print it for now   print("Received from %s: '%s'" % (chatMessage["content"], 
                                   sender["display_name"]))

For each new chat message from a visitor we need to decide what the response should be and possibly what other action the message might trigger on behalf of the user. For example if the visitor is requesting a password reset, we might also call the appropriate service in the back-end for resetting a password.

 

 

Connect to the chatbot service

In order to get the right answer to the visitor message we will call the chatbot service API (Watson Assistant in this example) and send the response from the service back to the visitor.
For the sake of simplicity, we’re using a continuous loop of reading and responding from/to a websocket. While it makes the workflow easier to understand, it becomes a challenge when you want to handle multiple messages from multiple visitors in the same time. There are few ways to handle this complexity in Python, probably one of the most popular is using an asynchronous library such as asyncio. This is beyond the scope of this tutorial, but you can check out this useful guide here.

 

while True:# receive websocket messagesmessage = ws.recv()data = json.loads(message)# make sure we listen to chat messages from the our subscriptionif "sig" in data and data["sig"] == 'DATA' and \
            data["subscription_id"] == subscription_id and \
            "payload" in data and "data" in data["payload"]: # the chat message structure will include the message string but 
  # also sender details chatMessage = data["payload"]["data"]["message"]["node"] sender = chatMessage["from"] # make sure the message is from a visitor if sender["__typename"] == "Visitor":   # we have to do something with the message, let's print it for now   print("Received from %s: '%s'" % (chatMessage["content"], 
                                      sender["display_name"]))   # call Watson Assistent to get the approapriate response to user's message   response = assistant.message(workspace_id="<workspace_id>",
                         input={"text": chatMessage["content"]})   chatbot_msg = "\n".join(response["output"]["text"])   print("Response from chatbot: '%s'" % (chatbot_msg))   # send the response back to the visitor   ws.send(json.dumps(sendMessageQuery(chatMessage["channel"]["id"], chatbot_msg)))

That’s it, now you have your first Zendesk Chat chatbot! Summarizing the steps, you start by authenticating the app to the livechat platform (as any agent would do), initialize/authenticate the chatbot service (Watson Assistant) and wait to receive new messages from visitors. When a new message is received, forward it to the chatbot service, get the appropriate response back and send it to the visitor.
This is a relatively simple workflow implementing a simple use case, although much more can be done to expand it with additional capabilities such as handover to agent or handling more complex dialog flows where context needs to be maintained for each visitor. More about this in the next tutorial!

 

 

Conclusion

As you can see, if you are using Zendesk Chat to support your customers, building a simple native chatbot is relatively easy using the Conversations API that was released recently. You also have the option to choose from the large variety of chatbot service providers.
However the challenges of building a chatbot goes beyond the actual implementation and integration between services. It starts with asking yourself what problems and questions my customers regularly have?
Which of these problems or questions can I streamline and automate so it becomes easier for my customers to resolve the problem or answer the question using a chatbot than getting in contact with one of your support reps.building a chatbot starts with asking yourself what problems and questions my customers regularly haveYou need to start by understanding your customers problems then work your way through the customer and user experience to deliver effective solutions to your customers.

Subscribe to our newsletter