webhooks

Reacting to timetracking events with Timeular Webhooks

In a previous post, we took a look at how to use the Timeular Public API.

This time we will take the next step and look at how we can build even more powerful applications. We can do this using the Webhooks API. It enables users to register callbacks, which are called when a certain action happens. For example, you could register a hook that https://example.org/my-entry-started is called every time you start a time entry.

The API is easy to use, but increases the potential for Timeular-based applications by a lot. It also enables you to use tools such as Zapier, which will be the topic of a future blog post as well. In this example, we will first sign into the Timeular API. Then we fetch the list of events we can subscribe to and subscribe to the “start tracking” and “stop tracking” events. Then, we will start an HTTP server with endpoints for the above mentioned hooks.

We will use Localtunnel to expose the HTTP server to the internet, so the Timeular API can call the URLs we register in the hook.

If this sounds complicated right now, don’t worry, we’ll go over every step one after the other. 🙂

Let’s get started!

Basic Setup

First, we create a new project using “cargo init” and add some dependencies.

We’ll make web requests to the Timeular API using the reqwest library, which uses the Tokio async runtime.

Since we’re going to both make requests to register our hooks and then run a server to receive requests from Timeular, we’ll also add Warp as an HTTP server.

Serde and the once_cell library are helpers for using JSON and creating a globally shared HTTP client.

Authentication and configuration

First, we’ll get some values from the environment. This configures our API credentials and the public URL our server will be reachable at.

In terms of the API credentials, to create them, go to https://profile.timeular.com/ and create a set of API key and API secret.

Keep in mind that the API secret won’t be visible to you after the first time, so copy and store it somewhere secure. We also need a way to register webhooks with a publicly reachable URL and as mentioned above, we’ll use Localtunnel to achieve this. Localtunnel will enable us to route a locally running server, for example on port 8000, to a publicly reachable DNS entry.

First, let’s take a look at how to expose a local server to the web. We first execute the following command:

Then, go to the URL returned from this command, and you will see an informational page regarding security implications. Once you read and understood it, click “continue” and from this point on, anyone will be able to use this URL to get to your running server. You can do this before you actually have a server running.

So, now let’s get to our first steps configuring the web server and fetching the authentication token:

First, we get the API key, API secret and the public URL we get from Localtunnel from our defined environment variables.

Then, we call the “sign_in” function, which looks like this:

As in our previous post, we send the API key and Token with a POST request to the Timeular API’s sign-in endpoint.

We get an authentication token back, which we have to put inside the “Authorization” header, as a Bearer token.

Subscribing to events

Now that we have our authentication token, we can start to make authenticated requests to the Timeular API. The first such request will be to fetch all events we can register a webhook on and then we will subscribe to both “tracking started” and “tracking stopped” events.

First, let’s create a “fetch_events” function:

Here, we call the “/webhooks/event” endpoint and essentially get a list of strings back. These describe the different events we can register webhooks on.

We call the function like this in “main”:

The next step is to register a subscription hook to the “tracking started” and “tracking stopped” events.

We will use “/webhooks/subscription” endpoint for that.

The requests we send to the subscription endpoint look like this:

So we use one of the event identifiers we got from our previous request and define a callback URL. That’s all there is to it. Once this is registered, every time the specified event happens at Timeular, the Timeular backend will send a POST request to the registered URL with the payload of said event.

Let’s look at how to register our events:

In both cases, we simply create the payload with our base URL from Localtunnel. Adding “started-tracking” and “stopped-tracking” at the end, which is where we will implement our callback handlers. The request is the same as the other authenticated Timeular requests and we call it in “main” like so:

After subscribing, these subscriptions should show up in our list of subscriptions. Keep in mind, that you can’t have more than 5 subscriptions per event active at any time. So if you’re in that situation, you’ll get an error.

Fetching the subscription list works like this:

And then we can call and print it like so:

We use the Warp library for our web server and define two incoming routes for started and stopped tracking:

The handlers themselves aren’t very exciting:

We simply log the incoming payloads, that’s all. But you can imagine all the fun things we could do here. For example, we could use the incoming data to create a time entry in a different system. Rr put it in a local database, or whatever – the options are endless! Of course we also need to define the payloads, which we’ll receive from the webhooks:

With all of that in place, the only thing left is to assemble and start the web server:

We also define a “/health” route, so we can test our LocalTunnel setup. Then we start a Warp server with the “serve” function, providing our routes, the port and the local IP to run on.

That’s it – let’s test if it actually works. 🙂

Testing

As mentioned in the beginning of the article, the first step is to run “Localtunnel”. With the URL we get from it, we can set our environment variables and start the HTTP server:

This will fetch our events, subscribe two hooks to the endpoints on our server, create these endpoints and start the HTTP server. Once this is done, we can switch over to the Timeular app, or we can simply use the application we built in our previous post, for starting and stopping tracking.

When you started and stopped the tracking, check the logs of the server – you should see the incoming requests with all their data.

And after creating the time entry:

Glorious – it works!

That’s it, you can find the source code for this example here.

Conclusion

This concludes the demonstration of how to use Timeular’s brand new Webhooks API, which enables you to react to your Timetracking events. This new functionality finally enables our users to build rich, complex applications and to integrate Timeular with their favorite tools in the way, which makes the most sense for them.
In the next post, we will take a look at how to use Zapier, for people who are not as comfortable coding their own integrations, to achieve many of the same benefits!