Hey there, fellow developer! Ready to dive into the world of Harvest API integration? You're in for a treat. Harvest's API is a powerhouse for time tracking and project management, and we're about to harness that power in C#. Buckle up!
Before we jump in, make sure you've got:
Let's kick things off:
Install-Package Newtonsoft.Json
Install-Package RestSharp
These bad boys will make our lives easier when dealing with JSON and HTTP requests.
Alright, authentication time! Harvest uses OAuth 2.0, but for simplicity, we'll use personal access tokens.
var client = new RestClient("https://api.harvestapp.com/v2/"); client.AddDefaultHeader("Authorization", "Bearer YOUR_ACCESS_TOKEN"); client.AddDefaultHeader("Harvest-Account-Id", "YOUR_ACCOUNT_ID");
Time to make our first request! Let's fetch some time entries:
var request = new RestRequest("time_entries", Method.GET); var response = client.Execute(request); if (response.IsSuccessful) { var timeEntries = JsonConvert.DeserializeObject<TimeEntriesResponse>(response.Content); // Do something awesome with your time entries } else { Console.WriteLine($"Error: {response.ErrorMessage}"); }
Now that we're rolling, let's cover the CRUD operations:
var newEntry = new RestRequest("time_entries", Method.POST); newEntry.AddJsonBody(new { project_id = 12345, task_id = 67890, spent_date = DateTime.Today.ToString("yyyy-MM-dd"), hours = 2.5 }); var createResponse = client.Execute(newEntry);
var updateEntry = new RestRequest($"time_entries/{entryId}", Method.PATCH); updateEntry.AddJsonBody(new { hours = 3.0 }); var updateResponse = client.Execute(updateEntry);
var deleteEntry = new RestRequest($"time_entries/{entryId}", Method.DELETE); var deleteResponse = client.Execute(deleteEntry);
Harvest uses cursor-based pagination. Here's how to handle it:
var request = new RestRequest("time_entries", Method.GET); request.AddQueryParameter("page", "1"); request.AddQueryParameter("per_page", "100"); var response = client.Execute(request); var data = JsonConvert.DeserializeObject<TimeEntriesResponse>(response.Content); while (!string.IsNullOrEmpty(data.Links.Next)) { request.Resource = data.Links.Next; response = client.Execute(request); data = JsonConvert.DeserializeObject<TimeEntriesResponse>(response.Content); // Process the data }
Want to get fancy? Try this:
request.AddQueryParameter("from", "2023-01-01"); request.AddQueryParameter("to", "2023-12-31"); request.AddQueryParameter("project_id", "12345"); request.AddQueryParameter("sort", "spent_date:desc");
Don't forget to wrap your API calls in try-catch blocks and log the responses:
try { var response = client.Execute(request); Log.Information($"API Response: {response.Content}"); // Process the response } catch (Exception ex) { Log.Error($"API Error: {ex.Message}"); }
Unit testing is your friend. Here's a quick example using xUnit:
[Fact] public void TestGetTimeEntries() { var client = new HarvestClient("YOUR_ACCESS_TOKEN", "YOUR_ACCOUNT_ID"); var entries = client.GetTimeEntries(); Assert.NotNull(entries); Assert.True(entries.Count > 0); }
And there you have it! You're now equipped to build a robust Harvest API integration in C#. Remember, this is just the beginning. Explore the Harvest API documentation for more endpoints and features.
Now go forth and code! Your time tracking game is about to level up. Happy harvesting!