class Harvesting::Client
A client for the Harvest API (version 2.0)
Constants
- DEFAULT_HOST
Attributes
Public Class Methods
Returns a new instance of `Client`
client = Client.new(access_token: "12345678", account_id: "98764")
@param [Hash] opts the options to create an API client @option opts [String] :access_token Harvest access token @option opts [String] :account_id Harvest account id
# File lib/harvesting/client.rb, line 20 def initialize(access_token: ENV['HARVEST_ACCESS_TOKEN'], account_id: ENV['HARVEST_ACCOUNT_ID']) @access_token = access_token.to_s @account_id = account_id.to_s if @account_id.length == 0 || @access_token.length == 0 raise ArgumentError.new("Access token and account id are required. Access token: '#{@access_token}'. Account ID: '#{@account_id}'.") end end
Public Instance Methods
@return [Harvesting::Models::Clients]
# File lib/harvesting/client.rb, line 35 def clients(opts = {}) Harvesting::Models::Clients.new(get("clients", opts), opts, harvest_client: self) end
@return [Array<Harvesting::Models::Contact>]
# File lib/harvesting/client.rb, line 40 def contacts get("contacts")["contacts"].map do |result| Harvesting::Models::Contact.new(result, harvest_client: self) end end
Creates an `entity` in your Harvest account.
@param entity [Harvesting::Models::Base] A new record in your Harvest account @return [Harvesting::Models::Base] A subclass of `Harvesting::Models::Base` updated with the response from Harvest
# File lib/harvesting/client.rb, line 89 def create(entity) url = "#{DEFAULT_HOST}/#{entity.path}" uri = URI(url) response = http_response(:post, uri, body: entity.to_hash) entity.attributes = JSON.parse(response.body) entity end
It removes an `entity` from your Harvest account.
@param entity [Harvesting::Models::Base] A record to be removed from your Harvest account @return [Hash] @raise [UnprocessableRequest] When HTTP response is not 200 OK
# File lib/harvesting/client.rb, line 114 def delete(entity) url = "#{DEFAULT_HOST}/#{entity.path}" uri = URI(url) response = http_response(:delete, uri) raise UnprocessableRequest.new(response.to_s) unless response.code.to_i == 200 JSON.parse(response.body) end
Performs a GET request and returned the parsed JSON as a Hash.
@param path [String] path to be combined with `DEFAULT_HOST` @param opts [Hash] key/values will get passed as HTTP (GET) parameters @return [Hash]
# File lib/harvesting/client.rb, line 128 def get(path, opts = {}) url = "#{DEFAULT_HOST}/#{path}" url += "?#{opts.map {|k, v| "#{k}=#{v}"}.join("&")}" if opts.any? uri = URI(url) response = http_response(:get, uri) JSON.parse(response.body) end
@return [Array<Harvesting::Models::Invoice>]
# File lib/harvesting/client.rb, line 67 def invoices(opts = {}) Harvesting::Models::Invoices.new(get("invoices", opts), opts, harvest_client: self) end
@return [Harvesting::Models::User]
# File lib/harvesting/client.rb, line 30 def me Harvesting::Models::User.new(get("users/me"), harvest_client: self) end
@return [Harvesting::Models::Projects]
# File lib/harvesting/client.rb, line 52 def projects(opts = {}) Harvesting::Models::Projects.new(get("projects", opts), opts, harvest_client: self) end
@return [Harvesting::Models::ProjectTaskAssignments]
# File lib/harvesting/client.rb, line 79 def task_assignments(opts = {}) project_id = opts.delete(:project_id) path = project_id.nil? ? "task_assignments" : "projects/#{project_id}/task_assignments" Harvesting::Models::ProjectTaskAssignments.new(get(path, opts), opts, harvest_client: self) end
@return [Harvesting::Models::Tasks]
# File lib/harvesting/client.rb, line 57 def tasks(opts = {}) Harvesting::Models::Tasks.new(get("tasks", opts), opts, harvest_client: self) end
@return [Harvesting::Models::TimeEntries]
# File lib/harvesting/client.rb, line 47 def time_entries(opts = {}) Harvesting::Models::TimeEntries.new(get("time_entries", opts), opts, harvest_client: self) end
Updates an `entity` in your Harvest account.
@param entity [Harvesting::Models::Base] An existing record in your Harvest account @return [Harvesting::Models::Base] A subclass of `Harvesting::Models::Base` updated with the response from Harvest
# File lib/harvesting/client.rb, line 101 def update(entity) url = "#{DEFAULT_HOST}/#{entity.path}" uri = URI(url) response = http_response(:patch, uri, body: entity.to_hash) entity.attributes = JSON.parse(response.body) entity end
@return [Harvesting::Models::ProjectUserAssignments]
# File lib/harvesting/client.rb, line 72 def user_assignments(opts = {}) project_id = opts.delete(:project_id) path = project_id.nil? ? "user_assignments" : "projects/#{project_id}/user_assignments" Harvesting::Models::ProjectUserAssignments.new(get(path, opts), opts, harvest_client: self) end
@return [Harvesting::Models::Users]
# File lib/harvesting/client.rb, line 62 def users(opts = {}) Harvesting::Models::Users.new(get("users", opts), opts, harvest_client: self) end
Private Instance Methods
# File lib/harvesting/client.rb, line 158 def auth_error?(response) response.code.to_i == 403 || response.code.to_i == 401 end
# File lib/harvesting/client.rb, line 138 def http_response(method, uri, opts = {}) response = nil http = HTTP["User-Agent" => "Harvesting Ruby Gem", "Authorization" => "Bearer #{@access_token}", "Harvest-Account-ID" => @account_id] params = {} if opts[:body] params[:json] = opts[:body] end response = http.send(method, uri, params) raise Harvesting::AuthenticationError.new(response.to_s) if auth_error?(response) raise Harvesting::UnprocessableRequest.new(response.to_s) if response.code.to_i == 422 raise Harvesting::RequestNotFound.new(uri) if response.code.to_i == 404 raise Harvesting::RateLimitExceeded.new(response.to_s) if response.code.to_i == 429 response end