Export Zendesk Tickets and Comments Using the API
Update: github changed the gist url structure, so we’ve updated the url for the gist to go to the right place. Sorry for the confusion.
We love Zendesk as a ticketing service for our support clients, but when we found out you cannot export Zendesk tickets without purchasing a larger plan, we were disappointed. As web developers, we pride ourselves on finding a way if one exists, utilizing the latest tools and methods to build solutions to our client’s problems. This case was not an exception.
Getting Started
The Good News
There’s hope yet! Zendesk provides a terrific API which is open to anyone with an account. With a little web development magic we can bend this to our will. They have endpoints for getting tickets, users, comments and a variety of other methods we aren’t going to be getting into in great detail this time around. That means we can export Zendesk tickets however we want using these web services!
To get started get the full code on Gist.
The Bad News
Unfortunately, this requires a little bit of development work to get everything to work. Don’t worry! We have you covered. We were able to find a Zendesk-specific API class written by Julien Renouard in PHP to get started. This just wraps the curl requests in the right way and provides some additional helper functionality when it comes to making requests and getting back results.
Working With the Code
The following code is meant to do one fairly niche thing, get all tickets from a particular organization, listing out title, comments and comment authors. This is about a bare-bones as you can get with these types of things. There is very little markup and just one usability enhancement to make it easier to digest the tickets. Ok, let’s get into it.
Setting Up Your Credentials
First, you need to enable access to the REST API through your account. Find this under Settings / Channels / API. They call it Token Access. Enable this and you’ll receive your very own API Key. Guard this with your life or at least change it if you lose it, release it to the public, etc. Jump down in the code until you find the following:
$face = new Zendesk( API_KEY, USERNAME, SUBDOMAIN ); $org_id = ORG_ID; $test = $face->call('/organizations/'.$org_id.''/tickets', array(), 'GET');
You want to replace your API_KEY with the one you just got from Zendesk. USERNAME is usually the email address you use to log into the site. SUBDOMAIN is the prefix to the url you use to access the site. In our case it’s ‘wdgdc’. Finally, you want to set ORG_ID to the id of the organization you want to export. The easiest way I found to get this id is to go to Zendesk under Settings / People and then click Organizations under the search box. Click on the organization you want to use and the ID will appear in the url after /organizations/.
Run it!
That’s all you need to do! Add this file to a server or to your localhost and run it. You should see a webpage with a list of all the titles of all tickets associated with the organization. To note, there aren’t any of the optimizations we usually put into functionality like this, so it might timeout or hit a memory limit. Be careful and never run this on a production server.
If you want to learn some more about how the rest of this code works, continue on.
Explanation of the Code
Users
One of the first things I noticed was the fact that comments only returned a user ID, so the following calls a list of all users in Zendesk and saves them out in their own array. We’ll use this later to match up the user id to the output we’re looking for.
$users = $face->call('/users', array(), 'GET'); $users = $users->users; $authors = array(); foreach($users as $user) { $authors[$user->id] = $user->name.' ('.$user->email.')'; }
Tickets
Next we need to iterate through the tickets we fetched from the organization earlier in our code (marked here by …). We want to grab the title, timestamp and description of each ticket and output that in a way that can be easily digested. One thing that was irksome, the description of the ticket was not filtered in any way. I opted for the easy route to make this show up correctly, htmlentities takes all the characters html normally uses for markup and encodes them for display on the web. In this way you can have html markup show up in the text rather than have the html markup get read by the browser. From there I wrapped it in pre tags to force the correct white space to show up.
$test = $face->call('/organizations/'.$org_id.''/tickets', array(), 'GET'); ... $tickets = $test->tickets; print 'Tickets
'; $ids = array(); foreach($tickets as $ticket) { print 'Subject: '.$ticket->subject.'
'; print 'Show Ticket'; print '