Automating Drudgery
Ahh, programming out of spite, the most sincere form of programming.
In this post I want to briefly talk about how worklog, a CLI (command-line-interface) tool that automates time bookings to Tempo and Personio, came to be and find out why time logging grinds my gears as much as it does.
In the Beginning There was Lazyness
I'm sure lots of people can relate to the drudgery that is booking your work times day in and out, but what makes that task such a drag? In the end it only takes about five minutes per day to complete so it really isn't that big of a deal when I'm being honest, but still, something in me dies everytime I need to do it.
I'd say for me it boils down to doing the same thing over and over again for days on end while, as a fellow Org Mode user, actually having all the required data already at hand.
As every good programmer I was captivated by the idea of automating this inhumane task and also neglicting my current side-project in favour of a shiny new one.
We Have the Technology
Finally the time for the computer science education can shine and pay off.
Taking care of Jira and Tempo was pretty straight forward as their APIs (Jira API, Tempo API) are actually pretty good (albeit slow). There is an endpoint to get all work log entries within a specific time range and other ones to create and delete single entries - that's simple API design I can get behind.
For authentication we just need to create a personal API token in Jira itself, which, at least at our instance at work, every user is allowed to do.
With that out of they way, I wrote a simple client implementation to interface with the Tempo API and some more code to parse .org
files and voilĂ we can sync our time entries to Tempo.
Pay to Win
Being able to synchronize data with Tempo was the biggest win as my employer requires us to book efforts on a per ticket basis and this can get quite hairy if you work on many tickets in a single day.
Personio is used to track general attendance and is much less annoying, mainly because there is less stuff to enter. But if I have all the data in Org Mode already I might as well use it.
Personio, as Jira and Tempo, offers a well-documented API to mingle with your time entries. Authentication is done via a personal API token as well that you can issue via the settings menu.
But why can't I find this entry in the settings?!
Haha, walked right into the neo-capitalism trap where it is not enough to sell subscribtion-based software but no, you also hide the more useful features behind a paywall to sequeeze every last cent out of your customers.
That kinda stinks, but as longs as data is displayed in their web application it is also accessible to us, even though it means retrieving it in a roundabout way.
By the power of pressing F12
I was able to reverse-engineer a basic client that pretends to be the Personio webapp. All it needs to work is a valid CSRF token and an active session ID (a.k.a. all the cookies that get set after the authentication).
My employer requires login via Microsoft Entra's OAuth2 flow so we're stuck with actually doing the full flow in the browser.
Remote Control
If there only were a way to remotely control one's web browser...
I can already hear astute readers with end-to-end testing experience scream SELENIUUUUM/ in the distance and yes, that's what I went with, sort of.
As it turns out there is a whole Webdriver standard that is implemented by most browsers and controlling, for example Safari, is as easy as installing the corresponding Webdriver implementation (on macOS safaridriver
comes pre-installed) and sending HTTP calls to its JSON API.
So I cobbled together a small library to do so from any Go program and with this I had the last piece of the puzzle and could finally book my attendance entries automatically ascends to workflow automation supremacy.
Of Sources and Sinks
While implementing the Personio sync and refactoring some things I introduced a new abstraction of sources and sinks. Sources are, ehm, sources of data and sinks are destinations where you can sync said data to.
Sources:
- Org files
- Clockify
Sinks:
- CSV file
- Jira Tempo
- Personio
As far as ordinary, but every sink is also a source and suddenly that opened up data flows I didn't even intend to support. For example you can now also sync data to Personio from Jira or export your entries from Personio to a CSV file.
I think that demonstrates quite well that some abstractions really are built different and that one can gain a lot of power and flexibility when deeply thinking about proper abstractions instead of wrapping everything to make it just a bit nicer to use (or you get lucky like I did).
Worth the Effort?
Last but not least, was it worth all the trouble to automate what's essentially a five minute task?
I initially wanted to say no, when just looking at the numbers but, while actually looking at the numbers, even that doesn't seem like a bad deal after all.
So let's assume I spent around 20 hours working on this project in total and I used to need 3 minutes to track my work times per day but now only 3 minutes per week (36 s / day), that means my break-even-point is reached in 272 days:
(let* ((seconds-spent (* 20 60 60)) (savings-per-day (- (* 5 60) 36)) (days-til-roi (/ seconds-spent savings-per-day))) (print days-til-roi))
#+RESULTS: : 272
That's not even a year and from that point onwards it saves around half a work-week annually and it only gets better the more people use it (currently two by any account).
But even more so it was worth it counting all the new things I have learned and I suppose that's what really matters in the end.
And it keeps me from going insane by repeating the same task over and over again, yes, that's what it's really all about.