This is the second part of “Make Data Actionable: Embed Product Usage Data into Salesforce”. We’ll dive into building custom Zendesk apps for our success team to improve resolution time and keep our customers happy.

Collecting all sorts of data on your customers’ behaviors and building custom dashboards that are displayed around the office is pretty rad. But for data to be actionable, we’ve found it helpful to go one step further: you have to put the right data in front of the right people at the right time. We’ve shown why and how you can do that for your sales team. But this can also apply to your customer success/technical support team.

In this post we’ll talk about how we added custom widgets to our Zendesk to reduce ticket resolution time, increase our team’s producitivity, and improve customer satisfaction.

Let’s dive in!

Minimize Resolution Time

Customers write in daily with implementation questions and issues. Our product has a huge surface area (we collect and distribute customer data to 160 tools and hide most of the complexity), so it can be tricky to identify precisely where something is going wrong. Is the issue in one of the million different ways the customer has implemented our library? Or between our logic and one of the hundreds of integrations?

In the first few weeks of our success team, we realized we were asking the same initial questions about libraries, integrations, and settings to initiate the debugging process. This was silly, because we already had this information stored somewhere.

Our success team needs instant access to user-level information to be any kind of efficient.

To make our customers happier and increase the efficiency of the team, we had to minimize this back and forth. Our solution included providing more context about the inquiring user to our success engineers.

Build a custom Zendesk App

We built our own custom Zendesk app that not only pulls relevant user information from our database, but also allows success engineers to extend trials and jump right into a query in Loggly (what we use to locate server-side errors).

The custom Zendesk app is on the right side of the ticket.

If you use Zendesk, then here are the steps to set this up.

1. Expose the necessary routes on a server for the Zendesk custom app to request data from.

For Segment, we added a route to our server with the endpoint that accepts an email and a secret token in the URL. Note that the actual URL pattern is different for security purposes.

Then our server will take the identifying parameters of the user, retrieve all necessary information (all projects, integrations, usage, and relevant timestamps) from our databases, render it into HTML via a template, and return the HTML.

Bonus: You can also create routes that’ll perform some action on your server. For instance, a POST request to a specific route could extend the trial of a user’s account, add a coupon code, or change the account type.

2. Create the custom Zendesk app.

Here’s a sample Zendesk app that the team has graciously provided the community. It’s a bit limited, but their comprehensive documentation makes up for it.

Zendesk exposes a set of ticket lifecycle event hooks, such as when a ticket is loaded or the window is resized. You can map your functions to these events. We used app.activatedproject.done (a request event, project being the name of a function that sends the ajax request to our server), and events.

Here is the code in app.js of our custom Zendesk app:

(function() {
  'use strict';

  return {

    // Set lifecycle events and hooks
    events: {
      'app.activated': 'init',
      'projects.done': 'renderProjects',
      '': 'updateProjects'

    // Called when this app is activated
    init: function() {

      // Set our server endpoint to get user information
      this.apiUrl = '';

      // Grab the secret from Zendesk
      this.secret = this.setting('secret');

      // Grab the email from Zendesk

    // Create AJAX object to send request to our server
    requests: {
      projects: function(email) {
        return {
          url: helpers.fmt('%@/%@/%@', this.apiUrl, email, this.secret),
          type: 'GET',
          dataType: 'json'
      // Docs on requests:

    // Send GET request to server with customer email
    updateProjects: function(email) {
      this.ajax('projects', email);

    // Add the HTML to #segment-projects
    renderProjects: function(data) {

The app.activated event (called each time the ticket is loaded on the browser) gathers the email and secret on the page (Zendesk provides a data API for grabbing data on the page), then sends a GET request to the specified route. Our server logic (code not shown) will take the email and secret, look up the user in our database, pull up all relevant project/library/usage information, compose that into HTML, and then return that as data.

The project.done event is fired when the data is returned, upon which we render it on the Zendesk ticket with jQuery on the defined template: this.$('#segment-projects').html(data.html).

To make sure the data stays updated for our success team, we also added the event. This means that when customers change their email address, the function updateProjects will fire, ultimately refreshing the data on the page by initiating the app.activated event.

3. Upload the Zendesk app.

The final step! This is pretty straight forward and you can follow the instructions here.

Leverage Contextual Data

Here are some other add-ons (out-of-the-box) Zendesk apps that we have added and found beneficial to our success team.

Deliver Analysis

Though data drives change and influences opinions, data by itself can be useless. Having the data isn’t enough! Our friends at Mode summarized it perfectly by stating the real job of analysts is to “deliver analysis, not charts”. As data nerds, it’s important that we go one step further and connect the dots for the intended audience. Putting data where people will use it is one step towards making the data more useful.

How are you making your data actionable and empowering your teams? Let us know on Twitter!