Language Detection in Help Scout with Zapier

I used Zapier to automatically tag the emails that come into Help Scout. For example, if we get an email in German, it will automatically be tagged language-de. In this post, I'm going to write about why this is important at Trello, my love affair with Zapier, and how I went about setting it up. Skip to the end if you only care about the setup.

Why language detection is important for Trello

Trello is available in over 20 languages. When someone writes to support in their native language, we try to write back in their language. Sometimes we have someone on staff who can handle non-English emails. Most of the time we use Unbabel.

Because international support is so important, I've wanted to get more data on which languages we have coming into the inbox. I'm also interested in automatically routing cases to native speakers. That speeds up how fast we're able to get back to those customers.

I thought about manual tagging, but I avoid manual tagging whenever possible because it slows people down, so I save it for only the most critical things we want to track.

My love affair with Zapier

A while back, Zapier launched a Translate Zap. Since Zapier already had a Help Scout integration, this meant I might be able to detect the language and tag cases as they came in. Almost. It's a bit more complicated than that, but first I want to share why I love Zapier.

I love Zapier. For the uninitiated, Zapier is a service that connects apps together. For example, when a new card shows up in Trello with the word "Zanzibar" in it, copy the details of that Trello card to a Google Sheet. It's really easy to connect things together.

But the real reason I love Zapier is because it's such a solid platform. I can code—coding isn't the problem—the problem I always have is finding a place for that code to live. Servers. Version control. Uptime. Logging. Patches. Security. All of that stuff.

At Trello, we have two internal support boxes for scripting and automation. They're great. Mercer, one of the members of my team, even solved the language detection problem in one of our internal scripts, but because that script is so important for identifying our priority support customers, it got hung up in the testing phase and never shipped. That's not Mercer's fault. We have a complex infrastructure.

Zapier takes away the complexity of shipping code to solve tiny (or big) problems. It's a superb platform. I can connect services visually or I can write custom Python (or Javascript) code. You can test everything right in the browser. If it fails in production, you get logs for each task and can re-run the task right in the browser. This is all stuff you would want in a production system and Zapier just throws it in as part of the product.

If I can, I always choose to host my hacky solutions in Zapier.

</love-letter>

Setting up Zapier to tag cases in Help Scout

As I alluded to earlier, setting up Zapier to tag cases in Help Scout is almost automatic. You get a "New Conversation" trigger in Zapier, but you don't have a similar "Update Conversation" action. That means you have to write custom code that uses the Help Scout API. No worries. I'm going to give you the code!

When you first set up your Zap, your Trigger is going to be a Help Scout "New Conversation". We configure it to look at our "Trello Support" mailbox. PRO TIP: As you set up your Zap, be sure to test each phase separately. This will save you headaches from trying to test everything at once at the end.

In the screenshot above, I have a "Run Python" zap for the 2nd step. You can skip that. I'm just filtering out some cruft in our inbox unique to our setup.

Add an action for "Detect Language." Under "Edit Template" in the "Text" section, I'm passing in the Help Scout Subject and Preview on separate lines. I wish I could pass in the full first thread, but that's not available in the default trigger, so Subject and Preview it is.

Finally, the last Run Python Zap is where the real configuration lies. In the "Edit Template" section, you're going to need to set up inputs for id, language, and mailbox, like so:

Here's the full code to paste into the code block. You'll need to replace the YOUR API KEY HERE text with your API key from Help Scout.

import base64
from requests import Request, Session
import json

HELP_SCOUT_API_KEY = 'YOUR API KEY HERE'
def query_helpscout(method, url, data=None, params=None):
  BASE_URL = "https://api.helpscout.net/v1/"
  auth = "Basic " + base64.b64encode(HELP_SCOUT_API_KEY + ":X")
  headers = {'Content-Type': 'application/json'
            , 'Accept' : 'application-json'
            , 'Authorization' : str(auth)
            , 'Accept-Encoding' : 'gzip, deflate'
            }

  s = Session()
  req = Request(method,  BASE_URL + url,
      data=json.dumps(data),
      headers=headers,
      params=params
  )

  prepped = s.prepare_request(req)

  resp = s.send(prepped
  )

  return resp

url = 'conversations/%s.json' % input.get('id')

response = query_helpscout('GET', url)
response.raise_for_status() # optional but good practice in case the call fails!
conversation = response.json()['item']

data = {}
data['tags'] = conversation['tags'] if conversation['tags'] else []
data['tags'].append('language-%s' % input.get('language'))

response = query_helpscout('PUT', url, data)
response.raise_for_status()

return {'id': 1234, 'rawHTML': response.text}
output = [{'id': 123, 'hello': 'world'}]

The return and output lines are from sample code and I didn't remove them, but they also don't matter. You're not doing anything with the output after this step.

If successful, every case that comes into Help Scout will automatically be tagged with the language in which it was written. Enjoy!