Back

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

Aug 15, 20245 minute read

Introduction

Hey there, fellow code wrangler! Ready to dive into the world of time tracking with Harvest? You're in for a treat. We're going to build a slick Harvest API integration using JavaScript. Buckle up!

Prerequisites

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

  • A Harvest account (duh!)
  • API credentials (grab 'em from your Harvest dashboard)
  • Node.js and npm installed (you're a pro, so I'm sure you've got this covered)

Project Setup

Let's get this party started:

mkdir harvest-integration && cd harvest-integration npm init -y npm install axios dotenv

Authentication

Harvest uses OAuth 2.0. Let's set it up:

const axios = require('axios'); require('dotenv').config(); const harvestApi = axios.create({ baseURL: 'https://api.harvestapp.com/v2', headers: { 'Authorization': `Bearer ${process.env.HARVEST_ACCESS_TOKEN}`, 'Harvest-Account-ID': process.env.HARVEST_ACCOUNT_ID } });

Pro tip: Store your tokens in a .env file. Your future self will thank you.

Making API Requests

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

async function getTimeEntries() { try { const response = await harvestApi.get('/time_entries'); return response.data; } catch (error) { console.error('Error fetching time entries:', error); } }

Core API Integrations

Here's how to create a new time entry:

async function createTimeEntry(projectId, taskId, hours) { try { const response = await harvestApi.post('/time_entries', { project_id: projectId, task_id: taskId, hours: hours }); return response.data; } catch (error) { console.error('Error creating time entry:', error); } }

Error Handling and Rate Limiting

Harvest has rate limits, so let's play nice:

const rateLimit = require('axios-rate-limit'); const harvestApi = rateLimit(axios.create({ // ... previous config }), { maxRequests: 100, perMilliseconds: 15 * 60 * 1000 });

Data Processing and Storage

Parse and store your data however you like. Here's a quick example using a local JSON file:

const fs = require('fs').promises; async function storeTimeEntries(entries) { await fs.writeFile('timeEntries.json', JSON.stringify(entries, null, 2)); }

Testing

Don't forget to test! Here's a quick Jest test to get you started:

test('fetches time entries', async () => { const entries = await getTimeEntries(); expect(entries).toBeDefined(); expect(Array.isArray(entries.time_entries)).toBe(true); });

Deployment Considerations

When deploying, remember:

  • Use environment variables for sensitive info
  • Keep your API keys secret (no committing to public repos!)

Conclusion

And there you have it! You've just built a Harvest API integration that would make any time-tracking enthusiast proud. Remember, the Harvest API docs are your friend for more advanced features. Now go forth and track time like a boss!

Happy coding! 🚀