-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathclockify_switch.sh
More file actions
executable file
·129 lines (106 loc) · 5.04 KB
/
clockify_switch.sh
File metadata and controls
executable file
·129 lines (106 loc) · 5.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#!/bin/bash
# ==============================================================================
# clockify_switch.sh
#
# A DevOps-friendly script to automate Clockify context switching.
# It automatically stops the current active timer and starts a new one based on
# a fuzzy search of your project names.
#
# Usage:
# ./clockify_switch.sh "infra" "Debugging database latency"
# ./clockify_switch.sh "client a" "Daily standup"
# ./clockify_switch.sh "" (Just stops the current timer)
# ==============================================================================
# Inputs
PROJECT_SEARCH=$1
DESCRIPTION=${2:-"Working on $PROJECT_SEARCH"}
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
CONFIG_FILE="$SCRIPT_DIR/.clockify_config"
# Load config if it exists
if [ -f "$CONFIG_FILE" ]; then
source "$CONFIG_FILE"
fi
# Ensure API Key is provided
if [ -z "$CLOCKIFY_API_KEY" ]; then
echo "❌ Error: CLOCKIFY_API_KEY is not set."
echo "Please configure it by running:"
echo " echo \"export CLOCKIFY_API_KEY='your_api_key_here'\" > $CONFIG_FILE"
exit 1
fi
# Ensure jq is installed (used for JSON parsing)
if ! command -v jq &> /dev/null; then
echo "❌ Error: 'jq' is not installed. Please install it (e.g., sudo apt install jq)."
exit 1
fi
API_BASE="https://api.clockify.me/api/v1"
# ------------------------------------------------------------------------------
# 1. Fetch User and Workspace info (and cache it for future runs)
# ------------------------------------------------------------------------------
if [ -z "$CLOCKIFY_USER_ID" ] || [ -z "$CLOCKIFY_WORKSPACE_ID" ]; then
echo "🔍 First run setup: Fetching User and Workspace info..."
USER_INFO=$(curl -s -H "X-Api-Key: $CLOCKIFY_API_KEY" "$API_BASE/user")
CLOCKIFY_USER_ID=$(echo "$USER_INFO" | jq -r '.id')
CLOCKIFY_WORKSPACE_ID=$(echo "$USER_INFO" | jq -r '.activeWorkspace')
if [ "$CLOCKIFY_USER_ID" == "null" ] || [ -z "$CLOCKIFY_USER_ID" ]; then
echo "❌ Error: Failed to fetch user info. Check if your API key is valid."
exit 1
fi
# Cache for next time to speed up the script
echo "export CLOCKIFY_USER_ID='$CLOCKIFY_USER_ID'" >> "$CONFIG_FILE"
echo "export CLOCKIFY_WORKSPACE_ID='$CLOCKIFY_WORKSPACE_ID'" >> "$CONFIG_FILE"
fi
# ------------------------------------------------------------------------------
# 2. Stop the currently running timer
# ------------------------------------------------------------------------------
# Clockify API requires time in UTC ISO 8601 format
CURRENT_TIME=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
echo "⏸️ Stopping any currently running timer..."
STOP_RESP=$(curl -s -o /dev/null -w "%{http_code}" -X PATCH "$API_BASE/workspaces/$CLOCKIFY_WORKSPACE_ID/user/$CLOCKIFY_USER_ID/time-entries" \
-H "X-Api-Key: $CLOCKIFY_API_KEY" \
-H "Content-Type: application/json" \
-d "{\"end\": \"$CURRENT_TIME\"}")
if [ "$STOP_RESP" == "200" ]; then
echo "✅ Successfully stopped the active timer."
else
echo "ℹ️ No active timer found (or HTTP $STOP_RESP)."
fi
# If no project is provided, our job is done. Exit.
if [ -z "$PROJECT_SEARCH" ]; then
echo "👋 No project specified. Exiting."
exit 0
fi
# ------------------------------------------------------------------------------
# 3. Find the Project ID using a case-insensitive substring match
# ------------------------------------------------------------------------------
echo "🔎 Searching for a project matching '$PROJECT_SEARCH'..."
# Fetch up to 200 projects from the workspace
PROJECTS=$(curl -s -H "X-Api-Key: $CLOCKIFY_API_KEY" "$API_BASE/workspaces/$CLOCKIFY_WORKSPACE_ID/projects?page-size=200")
# Use jq to perform a case-insensitive search and grab the first match
PROJECT_ID=$(echo "$PROJECTS" | jq -r --arg query "$PROJECT_SEARCH" '.[] | select(.name | ascii_downcase | contains($query | ascii_downcase)) | .id' | head -n 1)
PROJECT_NAME=$(echo "$PROJECTS" | jq -r --arg query "$PROJECT_SEARCH" '.[] | select(.name | ascii_downcase | contains($query | ascii_downcase)) | .name' | head -n 1)
if [ "$PROJECT_ID" == "null" ] || [ -z "$PROJECT_ID" ]; then
echo "❌ Error: Could not find any project matching '$PROJECT_SEARCH'."
exit 1
fi
# ------------------------------------------------------------------------------
# 4. Start the new timer
# ------------------------------------------------------------------------------
echo "▶️ Starting a new timer for '$PROJECT_NAME'..."
START_RESP=$(curl -s -X POST "$API_BASE/workspaces/$CLOCKIFY_WORKSPACE_ID/time-entries" \
-H "X-Api-Key: $CLOCKIFY_API_KEY" \
-H "Content-Type: application/json" \
-d "{
\"start\": \"$CURRENT_TIME\",
\"projectId\": \"$PROJECT_ID\",
\"description\": \"$DESCRIPTION\"
}")
ENTRY_ID=$(echo "$START_RESP" | jq -r '.id')
if [ "$ENTRY_ID" != "null" ] && [ -n "$ENTRY_ID" ]; then
echo "✅ Success! Timer is now running."
echo " - Project: $PROJECT_NAME"
echo " - Description: $DESCRIPTION"
else
echo "❌ Failed to start timer. Response details:"
echo "$START_RESP" | jq .
exit 1
fi