Skip to content

Instantly share code, notes, and snippets.

@matdave
Last active June 23, 2023 16:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save matdave/e96531c0f86f480529cff7b904f04857 to your computer and use it in GitHub Desktop.
Save matdave/e96531c0f86f480529cff7b904f04857 to your computer and use it in GitHub Desktop.
Clockify Python Scripts
# Script rewritten for PipeDream.com
import requests
import datetime
import base64
import os
# Wakatime API endpoint for getting time entries
WAKATIME_API_ENDPOINT = "https://wakatime.com/api/v1/users/current/summaries"
# Your Wakatime API Key
WAKATIME_API_KEY = os.environ["WAKATIME_API_KEY"]
# Clockify API endpoint for creating time entries
CLOCKIFY_API_ENDPOINT = "https://api.clockify.me/api/v1/workspaces/{workspace_id}/time-entries"
# Your Clockify API Key
CLOCKIFY_API_KEY = os.environ["CLOCKIFY_API_KEY"]
# Your Clockify Workspace ID
CLOCKIFY_WORKSPACE_ID = os.environ["CLOCKIFY_WORKSPACE_ID"]
def convert_wakatime_to_clockify(wakatime_api_key):
# Base64 encode the API key
wakatime_api_key = base64.b64encode(wakatime_api_key.encode("ascii"));
headers = {"Authorization": "Basic " + wakatime_api_key.decode("ascii")}
# Format Today
today = datetime.datetime.today()
if(today.hour < 12):
today = today - datetime.timedelta(days=1)
formatDay = today.strftime("%Y-%m-%d")
response = requests.get(WAKATIME_API_ENDPOINT, headers=headers, params={"start": formatDay, "end": formatDay})
if response.status_code == 200:
wakatime_data = response.json()
for item in wakatime_data['data'][0]['projects']:
start_time = today.strftime("%Y-%m-%dT00:00:00Z")
hours = f"{item['hours']:02}"
minutes = item['minutes']
if minutes < 5:
minutes = 0
elif minutes < 20:
minutes = 15
elif minutes < 35:
minutes = 30
elif minutes < 50:
minutes = 45
else:
minutes = 0
hours = f"{int(hours)+1:02}"
minutes = f"{minutes:02}"
end_time = today.strftime("%Y-%m-%dT"+str(hours)+":"+str(minutes)+":00Z")
if start_time == end_time:
continue
clockify_entry = {
"start": start_time,
"end": end_time,
"timeInterval": {
"start": start_time,
"end": end_time
},
"description": item['name'],
"projectId": os.environ["CLOCKIFY_PROJECT_ID"], # Optional: Add the project ID if needed
"taskId": None,
"billable": True,
"isLocked": True,
"tagIds": [],
"customFields": [],
}
clockify_headers = {
"X-Api-Key": CLOCKIFY_API_KEY,
"Content-Type": "application/json"
}
create_entry_url = CLOCKIFY_API_ENDPOINT.format(workspace_id=CLOCKIFY_WORKSPACE_ID)
response = requests.post(create_entry_url, headers=clockify_headers, json=clockify_entry)
if response.status_code == 201:
print("Time entry created successfully.")
else:
print("Failed to create time entry.")
print(response.json())
else:
print("Failed to retrieve Wakatime data.")
# Replace <your_clockify_api_key>, <your_clockify_workspace_id>, <your_clockify_project_id>, and <your_clockify_user_id>
# with your own values before running the script.
convert_wakatime_to_clockify(WAKATIME_API_KEY)
import requests
import os
from datetime import timedelta, datetime
from dotenv import load_dotenv
load_dotenv()
# Zendesk API credentials
ZENDESK_SUBDOMAIN = os.getenv("ZENDESK_SUBDOMAIN")
ZENDESK_TOKEN = os.getenv("ZENDESK_TOKEN")
ZENDESK_ORGANIZATION_ID = os.getenv("ZENDESK_ORGANIZATION_ID")
ZENDESK_STARTDATE = os.getenv("ZENDESK_STARTDATE")
# Clockify API credentials
CLOCKIFY_API_KEY = os.getenv("CLOCKIFY_API_KEY")
CLOCKIFY_WORKSPACE_ID = os.getenv("CLOCKIFY_WORKSPACE_ID")
CLOCKIFY_PROJECT_ID = os.getenv("CLOCKIFY_PROJECT_ID")
# Get Zendesk tickets
def get_zendesk_tickets():
zendesk_url = f"https://{ZENDESK_SUBDOMAIN}.zendesk.com/api/v2/search?query=type:ticket created>{ZENDESK_STARTDATE} organization:{ZENDESK_ORGANIZATION_ID}"
zendesk_headers = {
'Content-Type': 'application/json',
'Authorization': 'Basic ' + ZENDESK_TOKEN
}
response = requests.get(zendesk_url, headers=zendesk_headers)
response.raise_for_status()
tickets = response.json()['results']
return tickets
# Create time entry in Clockify
def create_clockify_time_entry(ticket):
create_entry_url = f"https://api.clockify.me/api/v1/workspaces/{CLOCKIFY_WORKSPACE_ID}/time-entries"
clockify_headers = {
'Content-Type': 'application/json',
'X-Api-Key': CLOCKIFY_API_KEY
}
# convert to datetime object 2023-06-14T16:33:22Z
starttime = datetime.strptime(ticket['created_at'], "%Y-%m-%dT%H:%M:%SZ")
# add one hour to the start time
endtime = starttime + timedelta(hours=1)
clockify_entry = {
'start': starttime.strftime("%Y-%m-%dT%H:%M:%SZ"),
'end': endtime.strftime("%Y-%m-%dT%H:%M:%SZ"),
'description': f"Zendesk Import: {ticket['subject']} https://modx.zendesk.com/agent/tickets/{ticket['id']}",
# You can adjust the project and task IDs based on your Clockify setup
'projectId': CLOCKIFY_PROJECT_ID,
'taskId': None,
'billable': True,
'isLocked': True,
'tagIds': [],
'customFields': [],
}
response = requests.post(create_entry_url, headers=clockify_headers, json=clockify_entry)
response.raise_for_status()
# Main function
def main():
tickets = get_zendesk_tickets()
for ticket in tickets:
create_clockify_time_entry(ticket)
print(f"Ticket {ticket['id']} moved to Clockify successfully.")
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment