Tracking hours with Clockify, fzf, jq and awk

For the current project, I need to track hours in Clockify. But as I was opening the webpage and filling in the hours, I felt dispassionate. So I decided to turn this activity into a joyful one.

It turns out that Clockify has an easy to use API. So I decided to build a script that 1) gets a list of all projects via an API call, 2) lets me interactively select a project, 3) lets me select duration I'd spent on the project that day, and 4) adds hours to the projects via an API call. To do the job, I summoned my favorite command-line tools:

  • HTTPie, a command-line HTTP client, out of the box ready for JSON REST APIs,
  • jq, a swiss-knife for parsing and transforming JSON,
  • awk, a gnu stronghold for text processing,
  • fzf, an interactive fuzzy search for the command-line,
  • cut and tr, text processing unix commands.

For example, to interactively select a project id I piped the tools together:

track-hours-select-a-project

Using the script almost every day, I'm now playfully enjoying the tracking routine.

Here's the full script:

#!/usr/bin/env bash

# fail on error, unused var and pipe failure
set -euo pipefail

# clockify api config
CLOCKIFY_BASE_URL='https://api.clockify.me/api/v1'
CLOCKIFY_DATE_FORMAT="%FT%T"

# let me select a project
PROJECT_ID=$(http $CLOCKIFY_BASE_URL/workspaces/"$CLOCKIFY_WORKSPACE_ID"/projects \
  'X-Api-Key':"$CLOCKIFY_API_KEY" | \
  jq -r ".[] | .id, .name" | \
  awk 'NR%2{printf "(%s) ", $0;next}1' | \
  fzf --nth=2.. | \
  cut -f1 -d' ' | \
  tr -d '()'
)

# let me pick how many hours I worked today
HOURS=$(seq 1 12 | awk '{print $0 " hours"}' | fzf | awk '{print $1}')

# start the day at 9:00am
TASK_STARTED_AT=$(date -v9H -v0M -v0S +$CLOCKIFY_DATE_FORMAT)

# and stop after $HOURS have passed
TASK_STOPPED_AT=$(date -j -v +"${HOURS}H" -f $CLOCKIFY_DATE_FORMAT "$TASK_STARTED_AT" +$DATE_FORMAT)

http -q $CLOCKIFY_BASE_URL/workspaces/"$CLOCKIFY_WORKSPACE_ID"/time-entries \
  'X-Api-Key':"$CLOCKIFY_API_KEY" \
  start="${TASK_STARTED_AT}Z" \
  end="${TASK_STOPPED_AT}Z" \
  projectId="$PROJECT_ID" \

echo "Done 🚀"

Would you like to connect? Subscribe via email or RSS , or follow me on Twitter!