Class: Freshbooks::Client Abstract

Inherits:
Object
  • Object
show all
Includes:
API::CRUD, API::Methods
Defined in:
lib/freshbooks/client.rb

Overview

This class is abstract.

Superclass that contains all logic and methods needed to send and parse XML from the Freshbooks API.

Since:

  • 0.1.0

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from API::CRUD

#create, #delete, #get, #list, #update

Methods included from API::Methods

#callbacks, #categories, #clients, #contractors, #currencies, #default_terms, #email_templates, #estimates, #expenses, #gateways, #invoices, #items, #languages, #payments, #projects, #receipts, #recurring, #reports, #staff, #systems, #tasks, #taxes, #time_entries

Constructor Details

#initialize(options = {}) {|_self| ... } ⇒ Client

Returns a new instance of Client

Yields:

  • (_self)

Yield Parameters:

Since:

  • 0.1.0


23
24
25
26
27
28
29
30
31
# File 'lib/freshbooks/client.rb', line 23

def initialize(options = {})
  options.each do |key, value|
    instance_variable_set("@#{key}", value)
  end

  @endpoint = underscore(self.class.to_s.split('::').last)

  yield(self) if block_given?
end

Instance Attribute Details

#api_urlString

the base URL of the API endpoint provided by Freshbooks

Since:

  • 0.1.0


19
20
21
# File 'lib/freshbooks/client.rb', line 19

def api_url
  @api_url
end

#tokenString

auth token provided by Freshbooks

Since:

  • 0.1.0


19
20
21
# File 'lib/freshbooks/client.rb', line 19

def token
  @token
end

Instance Method Details

#call(method, params = {}) ⇒ Hash

Makes an API call via the #post method.

Examples:

Create a callback.

call('callback.create', [:event, :uri], {event: 'Foo', uri: 'https://jesse.codes/'})
# => {...}

List projects.

call('project.list')
# => {...}

Since:

  • 0.1.0


51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/freshbooks/client.rb', line 51

def call(method, params = {})
  # unless params.empty?
  #   # ensure that params definied in the struct exist
  #   struct.each do |p|
  #     body[p] = params.fetch(p)
  #     params.delete(p)
  #   end
  #
  #   body.merge(params) unless params.empty?
  # end

  post_body = {method: method}
  post_body = post_body.merge(params) unless params.empty?

  post(post_body)
end

#hash_to_raw_xml(object, built = '') ⇒ String

Converts a raw hash into raw XML.

Examples:

convert hash to XML

data = {foo: {bar: {this: 'that'}}}
hash_to_raw_xml(data)
# => "<foo><bar><this>that</this></bar></foo>"

Since:

  • 0.1.0


129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/freshbooks/client.rb', line 129

def hash_to_raw_xml(object, built = '')
  case object
  when Hash
    case
    when object.count > 1
      object.each { |h| built += "<#{h.first.to_s}>#{hash_to_raw_xml(h.last)}</#{h.first.to_s}>" }
    when object.count == 1
      object.each { |h| built += "<#{h.first.to_s}>#{hash_to_raw_xml(h.last, built)}</#{h.first.to_s}>" }
    end
  when String
    built += object
  when Integer
    built += object.to_s
  end
  built
end

#optionsHash

Generates a hash of options to pass to Freshbooks::Client.

Since:

  • 0.1.0


149
150
151
152
153
154
# File 'lib/freshbooks/client.rb', line 149

def options
  {
    api_url: @api_url,
    token: @token
  }
end

#parse(xml_content) ⇒ Hash

Parses XML response into a hash.

Since:

  • 0.1.0


98
99
100
101
# File 'lib/freshbooks/client.rb', line 98

def parse(xml_content)
  MultiXml.parser = :nokogiri
  MultiXml.parse(xml_content)['response']
end

#post(body) ⇒ Object

Send post request to the API.

Since:

  • 0.1.0


71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/freshbooks/client.rb', line 71

def post(body)
  @connection = Faraday.new(@api_url) do |conn|
    conn.use FaradayMiddleware::Mashify
    conn.response :xml
    conn.basic_auth @token, 'X'
    conn.adapter Faraday.default_adapter
  end

  resp = @connection.post do |req|
    req.url '/api/2.1/xml-in'
    req.headers['Content-Type'] = 'application/xml'
    req.body = to_request(body)
  end

  body = resp.body.response
  if body.empty?
    resp.status
  else
    body
  end
end

#to_request(data_hash) ⇒ Object

Converts a data hash into a usable Freshbooks API XML request.

It parses the hash and removes relevant request attributes. Then it uses the method, #hash_to_raw_xml to convert it into XML.

Since:

  • 0.1.0


110
111
112
113
114
115
116
# File 'lib/freshbooks/client.rb', line 110

def to_request(data_hash)
  req_method = data_hash.delete(:method)
  '<?xml version="1.0" encoding="utf-8"?>' +
  "<request method=\"#{req_method}\">" +
    hash_to_raw_xml(data_hash) +
  '</request>'
end

#underscore(camel_cased_word) ⇒ Object

Converts a CamelCased word with an underscored_one.

Since:

  • 0.1.0


161
162
163
164
165
166
167
# File 'lib/freshbooks/client.rb', line 161

def underscore(camel_cased_word)
  camel_cased_word.gsub(/::/, '/').
  gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
  gsub(/([a-z\d])([A-Z])/,'\1_\2').
  tr("-", "_").
  downcase
end