Back

Step by Step Guide to Building a Clockify API Integration in JS

Aug 14, 20246 minute read

Introduction

Hey there, fellow dev! Ready to supercharge your time tracking game? Let's dive into building a Clockify API integration using JavaScript. We'll be leveraging the awesome clockify-ts package to make our lives easier. Buckle up!

Prerequisites

Before we jump in, make sure you've got:

  • Node.js and npm installed (you're a pro, so I'm sure you do)
  • A Clockify account and API key (grab one from your Clockify settings if you haven't already)

Setting up the project

Let's get this party started:

mkdir clockify-integration && cd clockify-integration npm init -y npm install clockify-ts axios dotenv

Configuring the Clockify client

Time to set up our Clockify client. Create an index.js file and let's roll:

require('dotenv').config(); const { ClockifyApi } = require('clockify-ts'); const clockify = new ClockifyApi({ apiKey: process.env.CLOCKIFY_API_KEY });

Pro tip: Create a .env file to store your API key. Keep it secret, keep it safe!

Basic API operations

Now for the fun part. Let's fetch some data:

async function getWorkspaces() { const workspaces = await clockify.workspaces.get(); console.log(workspaces); } async function getTimeEntries(workspaceId) { const timeEntries = await clockify.timeEntries.get(workspaceId); console.log(timeEntries); } async function createTimeEntry(workspaceId, projectId) { const newEntry = await clockify.timeEntries.create(workspaceId, { start: new Date(), projectId, description: "Building awesome stuff!" }); console.log(newEntry); }

Advanced operations

Ready to level up? Let's update and delete entries:

async function updateTimeEntry(workspaceId, timeEntryId, updates) { const updatedEntry = await clockify.timeEntries.update(workspaceId, timeEntryId, updates); console.log(updatedEntry); } async function deleteTimeEntry(workspaceId, timeEntryId) { await clockify.timeEntries.delete(workspaceId, timeEntryId); console.log("Entry deleted successfully"); }

When dealing with lots of data, remember to handle pagination:

async function getAllTimeEntries(workspaceId) { let page = 1; let allEntries = []; let entries; do { entries = await clockify.timeEntries.get(workspaceId, { page }); allEntries = [...allEntries, ...entries]; page++; } while (entries.length > 0); return allEntries; }

Error handling and best practices

Always wrap your API calls in try-catch blocks. Trust me, your future self will thank you:

async function safeApiCall(apiFunction) { try { return await apiFunction(); } catch (error) { console.error("API call failed:", error.message); } }

And don't forget about rate limiting. Be nice to the API!

Building a simple CLI tool

Let's put it all together in a simple CLI tool:

const [,, command, ...args] = process.argv; async function main() { switch (command) { case 'workspaces': await safeApiCall(getWorkspaces); break; case 'entries': await safeApiCall(() => getTimeEntries(args[0])); break; // Add more commands as needed default: console.log("Unknown command"); } } main();

Testing the integration

Don't forget to test! Here's a quick example using Jest:

jest.mock('clockify-ts'); test('getWorkspaces returns workspaces', async () => { const mockWorkspaces = [{ id: '1', name: 'Test Workspace' }]; ClockifyApi.mockImplementation(() => ({ workspaces: { get: jest.fn().mockResolvedValue(mockWorkspaces) } })); await getWorkspaces(); expect(console.log).toHaveBeenCalledWith(mockWorkspaces); });

Conclusion

And there you have it! You've just built a solid Clockify API integration. You're now equipped to track time like a boss. Remember, this is just the beginning – there's so much more you can do with the Clockify API. Keep exploring and building awesome stuff!

Resources

Now go forth and conquer those time tracking challenges! Happy coding! 🚀