Class: Marlens::HarvestApiV2::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/marlens/harvest_api_v2/client.rb

Constant Summary collapse

API_URL =
"https://api.harvestapp.com".freeze
USER_AGENT =
"marlens-harvest-api-v2/#{VERSION}".freeze

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(access_token:, account_id:, base_url: API_URL, executor: nil) ⇒ Client

Returns a new instance of Client.



21
22
23
24
25
26
# File 'lib/marlens/harvest_api_v2/client.rb', line 21

def initialize(access_token:, account_id:, base_url: API_URL, executor: nil)
  @access_token = access_token
  @account_id = 
  @base_url = base_url
  @executor = executor || method(:perform_request)
end

Class Method Details

.from_environment(environment: ENV) ⇒ Object

Raises:



12
13
14
15
16
17
18
19
# File 'lib/marlens/harvest_api_v2/client.rb', line 12

def self.from_environment(environment: ENV)
  access_token = environment.fetch("HARVEST_ACCESS_TOKEN", "")
   = environment.fetch("HARVEST_ACCOUNT_ID", "")
  raise Error, "HARVEST_ACCESS_TOKEN is required" if access_token.empty?
  raise Error, "HARVEST_ACCOUNT_ID is required" if .empty?

  new(access_token:, account_id:)
end

Instance Method Details

#active_personal_task_assignmentsObject



50
51
52
53
54
55
56
57
58
# File 'lib/marlens/harvest_api_v2/client.rb', line 50

def active_personal_task_assignments
  request(:get, "/v2/users/me/project_assignments", params: { per_page: 2000 })
    .fetch("project_assignments")
    .flat_map do |project_assignment|
      project_assignment.fetch("task_assignments", []).filter_map do |task_assignment|
        task_assignment.merge("project" => project_assignment.fetch("project")) if task_assignment["is_active"]
      end
    end
end

#active_task_assignmentsObject



46
47
48
# File 'lib/marlens/harvest_api_v2/client.rb', line 46

def active_task_assignments
  request(:get, "/v2/task_assignments", params: { is_active: true, per_page: 2000 }).fetch("task_assignments")
end

#create_time_entry(project_id:, task_id:, spent_date:, hours:, notes: nil) ⇒ Object



60
61
62
63
64
# File 'lib/marlens/harvest_api_v2/client.rb', line 60

def create_time_entry(project_id:, task_id:, spent_date:, hours:, notes: nil)
  body = { project_id:, task_id:, spent_date: spent_date.iso8601, hours: }
  body[:notes] = notes unless notes.nil? || notes.empty?
  request(:post, "/v2/time_entries", body:)
end

#request(method, path, params: {}, body: nil) ⇒ Object



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/marlens/harvest_api_v2/client.rb', line 28

def request(method, path, params: {}, body: nil)
  uri = URI.join(@base_url, path)
  uri.query = URI.encode_www_form(params) unless params.empty?
  request = request_class(method).new(uri)
  request["Content-Type"] = "application/json" if body
  request.body = JSON.generate(body) if body
  request["Authorization"] = "Bearer #{@access_token}"
  request["Harvest-Account-Id"] = @account_id
  request["User-Agent"] = USER_AGENT

  response = @executor.call(request)
  return JSON.parse(response.body) if response.is_a?(Net::HTTPSuccess)

  raise Error.new(response.code, error_message(response.body))
rescue JSON::ParserError
  raise Error, "Harvest API returned invalid JSON"
end