Customer Support via SMS with Zendesk

ZendeskA few weeks ago, I was given a challenge:

Replace email with SMS for customer support using Zendesk.

If you’re not familiar with Zendesk, it’s a flexible helpdesk system that allows customers create new helpdesk tickets by simply sending an email. Helpdesk staff can respond to the customer and apply complex workflows to tickets.  Best of all the whole thing is documented and logged so everyone can see what happened when.

Since I know the Twilio API, the only challenge was the Zendesk side of things. I was pleasantly surprised to find that it was also simple and easy to use, especially with the Zendesk PHP Library.

In this post I’ll walk you through setting up a simple Twilio application that allow your customers to create new Zendesk tickets and comment on their existing tickets simply by sending SMS messages.  I’ll also show you how to configure Zendesk so that your helpdesk staff can send ticket responses to your customers via SMS.

Of course if you just want to get implementing, the instructions for setting up the entire workflow can be found on Github along with the complete source code for the examples I’ll show in this post.

Pre-Launch Activities

  • A Twilio account. If you don’t already have a Twilio account sign up for a trial account.
  • A Zendesk account. If you don’t already have a Zendesk account sign up.

Once I’ve got those two accounts set up, there are a couple of configuration steps I need to do in order to get Twilio and Zendesk ready. Lets look at the Zendesk configuration first.

I know that I will need the customer’s phone number later so that the help desk can reply to the customer via a text message, but by default Zendesk tickets do not capture the number. In order to do that I’ve set up a new custom ticket field in Zendesk by logging into my Zendesk account, opening the Admin tab, selecting the Ticket Fields option and choosing the ‘add custom field’ option:

Next, I selected the Text field type:

I provided a field title, which in this case I called ‘Phone’, and then clicked the Add Field button:

My custom field should now shows up in the Ticket fields list.

As a last step I need to grab the unique ID for the custom field so that I can use it later in my application in order to tell to Zendesk where to store my customers phone number when I create a new ticket.

Since I won’t need this until I start writing my application code, I’ll just make a note of the field ID for now.

Now lets look at what I need to do to get Twilio ready. If you’re new to Twilio you might be asking yourself, “how does Twilio let me know that my customer has sent me a text message in the first place?”. When someone sends a text message to your Twilio phone number, Twilio will make an HTTP request to the URL that you have configured for the Message Request URL property of that phone number. In that request Twilio will include a bunch of data that I can use inside my application, including the body of the text message. That URL can, if it chooses, return a set of instructions called TwiML for Twilio to execute.

In my case I’ve configured my Twilio phone number to make a request to a file on my server named incoming.php:

In the next section I’ll walk you through the code in this file and show you how it takes the inbound SMS and creates a new Zendesk ticket from it.

Inbound: Create and Comment on Tickets

Now that I’ve got my Twilio and Zendesk accounts ready to go I can start writing the code that will take inbound SMS messages from Twilio and create new Zendesk tickets from them.

One of the first challenges I encountered in designing my application was how do I know what a customer wants to do when they send me a text message? Do they want to create a new ticket, or comment on an existing one? To allow my customers to tell me what they want to do I’ve devised a simple command system that lets my customers use a set of  keywords in their messages to tell me what they want.

In order to process incoming messages, I’ve split my application into two parts:

    • keyword command parser that is responsible for parsing out keywords from inbound SMS messages and
    • a command processor that is responsible for evaluating the keyword commands included in the message and executing the correct code path for those commands.

Parsing the commands from the incoming message is relatively simple:
$body = isset($_REQUEST['Body']) ?$_REQUEST['Body'] : 'An error occured from this number: '.$from;$commandDelimiterPosition = strpos($body, ' ');if ($commandDelimiterPosition==false) {$command = $body;} else {$command = substr($body, 0, $commandDelimiterPosition);$remainder = substr($body, $commandDelimiterPosition, strlen($body));}

Here I am using PHP’s strpos function to find the position of the first space, which is my command delimiter. Knowing where the space is I can the split the message body into two variables: $command and $remainder. The command variable holds the keyword that tells me what command the customer wants to run. The $remainder variable holds whatever text appears after the command which in my application will become the ticket or comment description text.

Now that I have a command, processing it is handled by a simple if block
if ($command == "menu") {//TODO: Return the app menu} else if ($command == "new") {//TODO: Create a new ticket} else if (is_numeric($command)) {//TODO: Add a comment to a specific ticket id} else {//TODO: Return the default message}

Unrecognized commands will fall to the end of the block and return a message prompting the customer to use the menu command:
$response = new Services_Twilio_Twiml();$response->message("Hello and thanks for the message. " ."Unfortunately I did not quite understand what you needed. " ."Try sending the word 'menu' for the list of commands.");

Here I am using the Twilio PHP helper library to generate TwiML containing the Message verb.  Returning this TwiML in response to Twilio’s HTTP request tells Twilio to send an SMS message right back to my customer.

Processing the ‘menu’ command looks very much the same:
$response->message("The available commands are:\r\new - create a new ticket\r\n" ."[id] - update this ticket ID\r\n" ."menu - show this menu");
Again I’m using the Twilio PHP helper library to generate TwiML containing the Message verb. This time the message contains the application menu, which tells the customer what commands are available to them.

Now that my customer knows the command for creating a new ticket I need to write the code in my PHP application to actually do it.

Lets pretend that a customer sends me this text message:
new Help! There are monkeys at my house. How do I get rid of them?

y application receives this text message and determines the customer wants to create a new ticket. To do that I’ll use the Zendesk API.

I start by creating a reusable method named getZendeskClient which uses my Zendesk API credentials to create and return an instance of the Zendeck PHP helper library.
function getZendeskClient() {$ZD_SUBDOMAIN = getenv('ZD_SUBDOMAIN');$ZD_USERNAME = getenv('ZD_USERNAME');$ZD_APITOKEN = getenv('ZD_APITOKEN');

$client = new ZendeskAPI($ZD_SUBDOMAIN, $ZD_USERNAME);
$client->setAuth(‘token’, $ZD_APITOKEN);

return $client;}
Once I create the instance of the helper library I can process the users command:
$result = $client->tickets()->create(array ('description' => $remainder,'subject' => substr($remainder, 0, 80),'requester_email' => $username,'custom_fields' =>array('id' => $ZD_FIELD,'value' => $from)));

 

$response->message("A new ticket has been created. To update, " ."reply with the command '" . $result->ticket->id . " [message]'");
Using the create method, I set the subject and description properties of the ticket to the $remainder variable I created earlier. Also, remember that custom field I created? In my application I’ve created a variable named $ZD_FIELD to hold the ID and am using it in this code to tell Zendesk to save the the customers phone number held in the $from variable.

I can test this code by sending a text message to my Twilio phone number. After sending the message I can see in Zendesk that a new ticket shows up in the tickets list:

Once the new ticket is created I use the Twilio PHP helper library to generate TwiML telling Twilio to return a text message to the customer. This message lets them know that their ticket was created and how they can add comments to it.

Lets now pretend that the customer wants to add a comment to their ticket. They can do this by sending another message like this:
48 The monkeys have started to attract owls. I really could use some help here.

Again, my application receives that text message and parses out the command ‘48’. Because this is a number I know that I need to add a comment to ticket number 48:

try {
$result = $client->tickets()->find(array(‘id’=>$command));
$ticket = $result->ticket;
$ticket_id = (string) $ticket->id;

$client->ticket($ticket_id)->update(
array(
‘comment’ => array(
‘public’ => true,
‘body’ => $remainder
)
)
);

$response->message(
“Your ticket has been updated.” .
“We’ll get on it as soon as we can.”
);

} catch (Exception $e) {$response->message("I could not find a ticket with the ID '" . $command . "'. " ."Are you sure that's the right ID?");}
Here I am using Zendesk PHP helper libraries find method to retrieve ticket number 48. If that ticket exists I use the update function to add a new comment to the ticket and return an SMS message letting the customer know the comment was added. If Zendesk is not able to find the ticket I return a different message letting the customer know that ticket with the specific ID could not be found.

As I did when creating a new ticket, I can test this code by sending a text message to my Twilio phone number, making sure to include the ID of the ticket I want to update. If everything works as expected, I’ll see that a comment has been added to my ticket:

Awesome! With just a little bit of PHP code I now have a system that lets my customers create and comment on support tickets. Next I’ll show you how to set up Zendesk so that helpdesk staff responses sent to customers via SMS.

Outbound: Reply to Tickets

So that helpdesk staff can send replies via text message, in Zendesk I have to configure a Target and a Trigger. A Target is a URL Zendesk can make HTTP requests to (like the Twilio Message URL I set earlier) and lets you integrate external applications or services into Zendesk, while a Trigger lets you specify what event in Zendesk will cause that request to be made.

First I want to first set up a Target that makes a request to the Messages endpoint in Twilio’s REST API. Making an HTTP POST to this endpoint tells Twilio to send a new text message. Then I want to create a Trigger that tells Zendesk to make this HTTP request whenever the help desk staff assigned to the ticket adds a comment to it.

To create the Target I open Settings -> Extensions -> Targets in Zendesk, click ‘add target’ and locate and select the ‘URL Target’ option.

Note that there is a Twilio Target in Zendesk which lets me send SMS messages to a specific phone number, but for my application I want to send to the number stored in each ticket which means I need to call the Twilio API directly, so I’m using the URL Target.

I start by giving the Target a sensible name. Next, in the URL field, I place a URL that points to the Twilio REST API endpoint for sending SMS:
https://api.twilio.com/2010-04-01/Accounts/[YOUR_ACCOUNT_SID]/Messages?From=[YOUR_TWILIO_PHONE_NUMBER]&To={{ticket.ticket_field_[CUSTOM_TICKET_FIELD_ID]}}&Body={{ticket.latest_public_comment}}
This URL includes all the parameters needed by Twilio to send a message. Note that when you create your own Target, you will need to replace Account SID, Twilio phone number and ticket field ID placeholders shown above in square brackets. The placeholders shown in double curly brackets are Zendesk placeholders and will be replaced by Zendesk when it makes its request to that URL.

Next I changed the Method drop down to POST, set the Attribute Name to ‘value’ and then fill in the Basic Authentication fields with my Twilio Account SID and AuthToken.

Finally, using the Test Target option I made sure that Zendesk was able to successfully send a text message using my Target configuration values.

To create a Trigger, I opened Manage -> Triggers and edited the “Notify requestor of comment update” trigger, changing the “Perform these actions” drop down to the Target name specified above.

Voila. Simple SMS-based customer support.

Wrapping it up

Creating an SMS-based customer support system is easy using Twilio and Zendesk.  Zendesk provides the helpdesk system which lets me track and respond to my customers help requests and Twilio provides the SMS service.

 

With just a little bit of system configuration and PHP glue, I’ve built a simple and useful bridge between the two systems.  Whenever someone sends an SMS to my Twilio number, a new ticket will be created. My customer service team can respond as needed and that response will be sent to the customer via SMS keeping the support thread connected together.  The best part is that the customer service team doesn’t have to do anything differently.

Try it out yourself today.  Download the full code from Github and let me know how you use SMS in your helpdesk system by dropping me an email or a tweet.