A client recently asked me to export records from Ticketmatic. Ticketmatic is a SAAS application for selling event tickets. They have a JSON API, so I figured it would be easy. Just send a GET request to some URL and parse the result as JSON right?

That doesn’t work because they use a hashing algorithm called HMAC-SHA256. This requires you to sign every request you make with a secret key to create a signature. After that, you have to put the signature, the current timestamp and an access key in the Authorization header of the request. Not just once but for every request!

 

 

There is an example header in the Ticketmatic API documentation but not much else for Ruby developers. Here is how I did it.

TDLR: here is the gist on Github if you don’t need the explanation.

Setup variables:

To create your own Authorization header you need some variables. Let’s start with the keys. You need an access key and a secret key. I got them from the clients’ account manager and put them in separate files (access_key.txt and secret_key.txt) and added the filenames to my .gitignore so they won’t be committed in the repository.

I did not use Rails for this tiny project but just a Ruby script called connect.rb. So open your editor again, create connect.rb and require the classes we need. Require ‘net/http’ will also require ‘uri’ so you don’t need to require it separately.

require 'openssl'
require 'Base64'
require 'net/http'

You can import the 2 files with keys we created earlier in your script by simply reading the first line with the File.open command and then strip away any unnecessary spaces with .strip.

access_key = File.open('access_key.txt', &:readline).strip
secret_key = File.open('secret_key.txt', &:readline).strip

The next thing we need is the current time in the right format:

time = Time.now.utc.strftime('%Y-%m-%dT%H:%M:%S')

And the Ticketmatic account name:

name = 'aikes-ticketmatic'

Here is the magic part where we use the variables we just created to generate the HMAC part:

hmac = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), 
       secret_key, access_key + name + time)

Next up is the uri we want to connect to. This is the Ticketmatic URL, the name of your account and the information you want from Ticketmatic. In this example I use ‘/diagnostics/time’. That will simply return the current time if you did everything right. This is also something that every API user can request so we won’t have any issues with permissions.

uri = URI("https://apps.ticketmatic.com/api/1/#{name}/diagnostics/time")

We are almost there. Let’s set up a request and add the ‘Authorization’ header to it.

req = Net::HTTP::Get.new(uri)
req['Authorization'] = "TM-HMAC-SHA256 key=#{access_key} ts=#{time} sign=#{hmac}"

And then run the request and return the results:

result = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
return result.body

Running the script:

If you named the script connect.rb like I did you can run it with “ruby connect.rb”. And if all goes well you’ll see something like this:

{"systemtime":"2018-10-26T11:59:18"}

That’s the system time on the Ticketmatic server returned to you in JSON format.

That’s it, we did the whole HMAC-SHA256 thing and got the time back. A next step is to change the URL to something useful like /contacts. You can find all of the available operations in the Ticketmatic API documentation.

Send a SQL query if you need many records

If you need a lot of records you can send SQL queries to the API. I’ve never seen this before but it works really well. The query was created by Ticketmatic for me and was 50 lines long… You can send the queries to “/tools/queries/export/” and put the query itself in the body of the request.

req = Net::HTTP::Post.new(uri, 'Content-Type' => 'application/json')
req.body = {query: your_query}.to_json

Of course, your_query is the query you want to execute.