basecrm 0.1.2 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (101) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +2 -2
  3. data/README.md +273 -17
  4. data/lib/basecrm.rb +185 -1
  5. data/lib/basecrm/configuration.rb +59 -0
  6. data/lib/basecrm/envelope.rb +7 -0
  7. data/lib/basecrm/errors.rb +65 -0
  8. data/lib/basecrm/http_client.rb +91 -0
  9. data/lib/basecrm/middlewares/oauth_bearer_token.rb +18 -0
  10. data/lib/basecrm/middlewares/raise_error.rb +31 -0
  11. data/lib/basecrm/model.rb +6 -0
  12. data/lib/basecrm/models/account.rb +31 -0
  13. data/lib/basecrm/models/address.rb +22 -0
  14. data/lib/basecrm/models/associated_contact.rb +19 -0
  15. data/lib/basecrm/models/contact.rb +88 -0
  16. data/lib/basecrm/models/deal.rb +58 -0
  17. data/lib/basecrm/models/lead.rb +79 -0
  18. data/lib/basecrm/models/loss_reason.rb +22 -0
  19. data/lib/basecrm/models/note.rb +28 -0
  20. data/lib/basecrm/models/pipeline.rb +19 -0
  21. data/lib/basecrm/models/source.rb +22 -0
  22. data/lib/basecrm/models/stage.rb +34 -0
  23. data/lib/basecrm/models/tag.rb +25 -0
  24. data/lib/basecrm/models/task.rb +46 -0
  25. data/lib/basecrm/models/user.rb +31 -0
  26. data/lib/basecrm/paginated_resource.rb +32 -0
  27. data/lib/basecrm/services/accounts_service.rb +33 -0
  28. data/lib/basecrm/services/associated_contacts_service.rb +91 -0
  29. data/lib/basecrm/services/contacts_service.rb +138 -0
  30. data/lib/basecrm/services/deals_service.rb +137 -0
  31. data/lib/basecrm/services/leads_service.rb +140 -0
  32. data/lib/basecrm/services/loss_reasons_service.rb +133 -0
  33. data/lib/basecrm/services/notes_service.rb +134 -0
  34. data/lib/basecrm/services/pipelines_service.rb +50 -0
  35. data/lib/basecrm/services/sources_service.rb +133 -0
  36. data/lib/basecrm/services/stages_service.rb +52 -0
  37. data/lib/basecrm/services/tags_service.rb +132 -0
  38. data/lib/basecrm/services/tasks_service.rb +141 -0
  39. data/lib/basecrm/services/users_service.rb +83 -0
  40. data/lib/basecrm/version.rb +3 -0
  41. data/spec/factories/associated_contact.rb +14 -0
  42. data/spec/factories/contact.rb +27 -0
  43. data/spec/factories/deal.rb +17 -0
  44. data/spec/factories/lead.rb +26 -0
  45. data/spec/factories/loss_reason.rb +11 -0
  46. data/spec/factories/note.rb +13 -0
  47. data/spec/factories/source.rb +11 -0
  48. data/spec/factories/tag.rb +12 -0
  49. data/spec/factories/task.rb +15 -0
  50. data/spec/services/accounts_service_spec.rb +16 -0
  51. data/spec/services/associated_contacts_service_spec.rb +43 -0
  52. data/spec/services/contacts_service_spec.rb +58 -0
  53. data/spec/services/deals_service_spec.rb +58 -0
  54. data/spec/services/leads_service_spec.rb +58 -0
  55. data/spec/services/loss_reasons_service_spec.rb +58 -0
  56. data/spec/services/notes_service_spec.rb +58 -0
  57. data/spec/services/pipelines_service_spec.rb +23 -0
  58. data/spec/services/sources_service_spec.rb +58 -0
  59. data/spec/services/stages_service_spec.rb +23 -0
  60. data/spec/services/tags_service_spec.rb +58 -0
  61. data/spec/services/tasks_service_spec.rb +58 -0
  62. data/spec/services/users_service_spec.rb +39 -0
  63. data/spec/spec_helper.rb +24 -12
  64. data/spec/support/client_helpers.rb +19 -0
  65. metadata +160 -71
  66. data/.gitignore +0 -20
  67. data/.rspec +0 -2
  68. data/.travis.yml +0 -6
  69. data/Gemfile +0 -4
  70. data/Rakefile +0 -8
  71. data/basecrm.gemspec +0 -23
  72. data/lib/base_crm.rb +0 -24
  73. data/lib/base_crm/account.rb +0 -11
  74. data/lib/base_crm/api_client_ext.rb +0 -6
  75. data/lib/base_crm/config.rb +0 -21
  76. data/lib/base_crm/contact.rb +0 -44
  77. data/lib/base_crm/custom_fieldable.rb +0 -32
  78. data/lib/base_crm/deal.rb +0 -50
  79. data/lib/base_crm/forecasting.rb +0 -12
  80. data/lib/base_crm/lead.rb +0 -36
  81. data/lib/base_crm/note.rb +0 -15
  82. data/lib/base_crm/noteable.rb +0 -15
  83. data/lib/base_crm/related_object_scope.rb +0 -35
  84. data/lib/base_crm/resource.rb +0 -14
  85. data/lib/base_crm/session.rb +0 -48
  86. data/lib/base_crm/source.rb +0 -14
  87. data/lib/base_crm/task.rb +0 -16
  88. data/lib/base_crm/taskable.rb +0 -15
  89. data/lib/base_crm/version.rb +0 -3
  90. data/spec/base_crm/account_spec.rb +0 -20
  91. data/spec/base_crm/contact_spec.rb +0 -92
  92. data/spec/base_crm/deal_spec.rb +0 -138
  93. data/spec/base_crm/forecasting_spec.rb +0 -34
  94. data/spec/base_crm/lead_spec.rb +0 -63
  95. data/spec/base_crm/note_spec.rb +0 -20
  96. data/spec/base_crm/resource_mixin_spec.rb +0 -26
  97. data/spec/base_crm/session_spec.rb +0 -97
  98. data/spec/base_crm/source_spec.rb +0 -20
  99. data/spec/base_crm/task_spec.rb +0 -21
  100. data/spec/support/noteable_shared_examples.rb +0 -64
  101. data/spec/support/taskable_shared_examples.rb +0 -69
@@ -0,0 +1,59 @@
1
+ require 'uri'
2
+
3
+ module BaseCRM
4
+ class Configuration
5
+ attr_reader :access_token
6
+ attr_reader :base_url
7
+ attr_reader :user_agent
8
+ attr_reader :timeout
9
+ attr_reader :verify_ssl
10
+
11
+ attr_reader :logger, :verbose
12
+ alias_method :debug?, :verbose
13
+
14
+ def initialize(options={})
15
+ @access_token = options[:access_token]
16
+ @base_url = options[:base_url] || "https://api.getbase.com"
17
+ @user_agent = options[:user_agent] || "BaseCRM/v2 Ruby/#{VERSION}"
18
+ @logger = options[:logger]
19
+ @verbose = !!options[:verbose]
20
+ @timeout = options[:timeout] || 30
21
+ @verify_ssl = options.fetch(:verify_ssl, true)
22
+ end
23
+
24
+ def validate!
25
+ unless @access_token
26
+ raise ConfigurationError.new('No access token provided. '\
27
+ 'Set your access token during client initialization using: '\
28
+ '"Base::Client.new(access_token: <YOUR_PERSONAL_ACCESS_TOKEN>)".')
29
+ end
30
+
31
+ if @access_token =~ /\s/
32
+ raise ConfigurationError.new('Provided access token is invalid '\
33
+ 'as it contains disallowed characters. '\
34
+ 'Please double-check your access token.')
35
+ end
36
+
37
+ if @access_token.length != 64
38
+ raise ConfigurationError.new('Provided access token is invalid '\
39
+ 'as it has invalid length. '\
40
+ 'Please double-check your access token.')
41
+
42
+ end
43
+
44
+ unless /\A#{URI.regexp(%w(http https)).to_s}\z/.match(@base_url)
45
+ raise ConfigurationError.new('Provided base url is invalid '\
46
+ 'as it is not a valid URI. '\
47
+ 'Please make sure it includes the scheme part, both http and https are accepted, '\
48
+ 'and the hierarchical part.')
49
+ end
50
+
51
+ end
52
+
53
+ def inspect
54
+ instance_variables.map { |ivar|
55
+ "#{ivar}=#{self.instance_variable_get(ivar)}"
56
+ }.join("\n")
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,7 @@
1
+ module BaseCRM
2
+ module Envelope
3
+ def self.wrap(data)
4
+ JSON.dump({data: data})
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,65 @@
1
+ module BaseCRM
2
+ class ConnectionError < StandardError
3
+ end
4
+
5
+ class ConfigurationError < StandardError
6
+ end
7
+
8
+ class BaseError < StandardError
9
+ attr_reader :code, :message, :details
10
+
11
+ def initialize(error)
12
+ @data = error[:error]
13
+ @meta = error[:meta]
14
+
15
+ @code = @data[:code]
16
+ @message = @data[:message]
17
+ @details = @data[:details]
18
+ end
19
+
20
+ def to_s
21
+ "code=#{@code} message=#{message} details=#{details}"
22
+ end
23
+ end
24
+
25
+ class RequestError < BaseError
26
+ end
27
+
28
+ class ResourceError < BaseError
29
+ attr_reader :resource, :field
30
+
31
+ def initialize(error)
32
+ super
33
+
34
+ @resource = @data[:resource]
35
+ @field = @data[:field]
36
+ end
37
+
38
+ def to_s
39
+ super + " resource=#{@resource} field=#{@field}"
40
+ end
41
+ end
42
+
43
+ class ServerError < BaseError
44
+ end
45
+
46
+ class ErrorsCollection < StandardError
47
+ attr_reader :errors
48
+
49
+ attr_reader :http_status, :logref
50
+ alias_method :request_id, :logref
51
+
52
+
53
+ def initialize(errors, meta)
54
+ @errors = errors
55
+
56
+ @http_status = meta[:http_status]
57
+ @logref = meta[:logref]
58
+ end
59
+
60
+ def to_s
61
+ status = "[#{@logref}] http_status=#{@http_status}\n"
62
+ status + @errors.map(&:to_s).join("\n")
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,91 @@
1
+ require_relative 'middlewares/oauth_bearer_token'
2
+ require_relative 'middlewares/raise_error'
3
+
4
+ module BaseCRM
5
+ class HttpClient
6
+
7
+ attr_reader :headers
8
+
9
+ def initialize(config)
10
+ @config = config
11
+
12
+ @headers = {
13
+ 'User-Agent' => config.user_agent,
14
+ 'Accept' => 'application/json'
15
+ }
16
+
17
+ @api_version = "/v2"
18
+
19
+ options = {
20
+ # timeout: config.timeout
21
+ }
22
+ options[:ssl] = { verify: false } unless config.verify_ssl
23
+
24
+ @client = Faraday.new(config.base_url, options) do |faraday|
25
+ faraday.use BaseCRM::Middlewares::OAuthBearerToken, config.access_token
26
+ faraday.use BaseCRM::Middlewares::RaiseError
27
+ faraday.response :logger, config.logger if config.debug?
28
+
29
+ faraday.adapter Faraday.default_adapter
30
+ end
31
+ end
32
+
33
+ def get(path, params={})
34
+ request(:get, path, params)
35
+ end
36
+
37
+ def post(path, body={})
38
+ request(:post, path, body)
39
+ end
40
+
41
+ def put(path, body={})
42
+ request(:put, path, body)
43
+ end
44
+
45
+ def delete(path, params={})
46
+ request(:delete, path, params)
47
+ end
48
+
49
+ def request(method, path, data={})
50
+ options = {
51
+ headers: @headers
52
+ }
53
+
54
+ case method.to_s.downcase.to_sym
55
+ when :get, :head, :delete
56
+ options[:query] = encode_params(data) unless data.empty?
57
+ else
58
+ unless data.empty?
59
+ options[:headers]['Content-Type'] = 'application/json'
60
+ options[:body] = Envelope.wrap(data)
61
+ end
62
+ end
63
+
64
+ path = "#{@api_version}#{path}"
65
+
66
+ res = instance_eval <<-RUBY, __FILE__, __LINE__ + 1
67
+ @client.#{method}(path) do |req|
68
+ req.body = options[:body] if options[:body]
69
+ req.headers.update(options[:headers])
70
+ req.params.update(options[:query]) if options[:query]
71
+ end
72
+ RUBY
73
+
74
+ [res.status, res.headers, extract_body(res)]
75
+ rescue Faraday::Error::ConnectionFailed => e
76
+ raise ConnectionError, e.message
77
+ end
78
+
79
+ private
80
+ def encode_params(params)
81
+ params.map { |k, v|
82
+ v.is_a?(Array) ? [k, v.join(',')] : [k, v]
83
+ }.to_h
84
+ end
85
+
86
+ def extract_body(res)
87
+ content_type = res.headers['Content-Type']
88
+ content_type && content_type.include?('json') ? JSON.parse(res.body, symbolize_names: true) : res.body
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,18 @@
1
+ module BaseCRM
2
+ module Middlewares
3
+ class OAuthBearerToken < Faraday::Middleware
4
+
5
+ def initialize(app, access_token)
6
+ super app
7
+ @access_token = access_token
8
+ end
9
+
10
+
11
+ def call(env)
12
+ env[:request_headers]["Authorization"] = "Bearer #{@access_token}"
13
+ @app.call(env)
14
+ end
15
+
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,31 @@
1
+ module BaseCRM
2
+ module Middlewares
3
+ class RaiseError < Faraday::Response::Middleware
4
+
5
+ def on_complete(env)
6
+ status = env[:status]
7
+ return if (200...300).member?(status)
8
+
9
+ content_type = env[:response_headers]['content-type']
10
+
11
+ unless content_type.include?('json')
12
+ raise "status=#{status} error=Unknown error occurred."
13
+ end
14
+
15
+ error_klass = case status
16
+ when 422 then BaseCRM::ResourceError
17
+ when 400...500 then BaseCRM::RequestError
18
+ when 500...600 then BaseCRM::ServerError
19
+ end
20
+
21
+ raise errors_collection(env, error_klass)
22
+ end
23
+
24
+ def errors_collection(env, error_klass)
25
+ envelope = JSON.parse(env[:body], symbolize_names: true)
26
+ errors = envelope[:errors]
27
+ ErrorsCollection.new(errors.map { |e| error_klass.new(e) }, envelope[:meta])
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,6 @@
1
+ require 'ostruct'
2
+
3
+ module BaseCRM
4
+ class Model < OpenStruct
5
+ end
6
+ end
@@ -0,0 +1,31 @@
1
+ # WARNING: This code is auto-generated from the BaseCRM API Discovery JSON Schema
2
+
3
+ module BaseCRM
4
+ class Account < Model
5
+ # @!attribute [r] created_at
6
+ # @return [DateTime] Date and time of the account's creation in UTC (ISO8601 format).
7
+ # attr_reader :created_at
8
+ # @!attribute [r] id
9
+ # @return [Integer] Unique identifier of the account.
10
+ # attr_reader :id
11
+ # @!attribute [r] updated_at
12
+ # @return [DateTime] Date and time of the last update in UTC (ISO8601 format).
13
+ # attr_reader :updated_at
14
+
15
+ # @!attribute [rw] currency
16
+ # @return [String] Currency of the account as the 3-character currency code in ISO4217 format.
17
+ # attr_accessor :currency
18
+ # @!attribute [rw] name
19
+ # @return [String] Full name of the account.
20
+ # attr_accessor :name
21
+ # @!attribute [rw] phone
22
+ # @return [String] Contact phone number of the account.
23
+ # attr_accessor :phone
24
+ # @!attribute [rw] time_format
25
+ # @return [String] Time format used for the account. Either 12-hour clock `12H` or 24-hour clock `24H`.
26
+ # attr_accessor :time_format
27
+ # @!attribute [rw] timezone
28
+ # @return [String] Timezone of the account as the offset from Coordinated Universal Time (UTC) in the format `UTC(+|-)[hh]:[mm]`.
29
+ # attr_accessor :timezone
30
+ end
31
+ end
@@ -0,0 +1,22 @@
1
+ # WARNING: This code is auto-generated from the BaseCRM API Discovery JSON Schema
2
+
3
+ module BaseCRM
4
+ class Address < Model
5
+
6
+ # @!attribute [rw] city
7
+ # @return [String] City name.
8
+ # attr_accessor :city
9
+ # @!attribute [rw] country
10
+ # @return [String] Country name.
11
+ # attr_accessor :country
12
+ # @!attribute [rw] line1
13
+ # @return [String] Line 1 of the address e.g. number, street, suite, apt #, etc.
14
+ # attr_accessor :line1
15
+ # @!attribute [rw] postal_code
16
+ # @return [String] Zip code or equivalent.
17
+ # attr_accessor :postal_code
18
+ # @!attribute [rw] state
19
+ # @return [String] State name.
20
+ # attr_accessor :state
21
+ end
22
+ end
@@ -0,0 +1,19 @@
1
+ # WARNING: This code is auto-generated from the BaseCRM API Discovery JSON Schema
2
+
3
+ module BaseCRM
4
+ class AssociatedContact < Model
5
+ # @!attribute [r] created_at
6
+ # @return [DateTime] Date and time that the associated contact was created in UTC (ISO8601 format).
7
+ # attr_reader :created_at
8
+ # @!attribute [r] updated_at
9
+ # @return [DateTime] Date and time of the last update on the associated contact in UTC (ISO8601 format).
10
+ # attr_reader :updated_at
11
+
12
+ # @!attribute [rw] contact_id
13
+ # @return [Integer] Unique identifier of the contact to be associated with the deal.
14
+ # attr_accessor :contact_id
15
+ # @!attribute [rw] role
16
+ # @return [String] Role name.
17
+ # attr_accessor :role
18
+ end
19
+ end
@@ -0,0 +1,88 @@
1
+ # WARNING: This code is auto-generated from the BaseCRM API Discovery JSON Schema
2
+
3
+ module BaseCRM
4
+ class Contact < Model
5
+ # @!attribute [r] created_at
6
+ # @return [DateTime] Date and time that the record was created in UTC ISO8601 format.
7
+ # attr_reader :created_at
8
+ # @!attribute [r] creator_id
9
+ # @return [Integer] The unique identifier of the user the contact was created by.
10
+ # attr_reader :creator_id
11
+ # @!attribute [r] id
12
+ # @return [Integer] The unique identifier of the contact.
13
+ # attr_reader :id
14
+ # @!attribute [r] updated_at
15
+ # @return [DateTime] Date and time of the record's last update in UTC ISO8601 format.
16
+ # attr_reader :updated_at
17
+
18
+ # @!attribute [rw] address
19
+ # @return [Address]
20
+ # attr_accessor :address
21
+ # @!attribute [rw] contact_id
22
+ # @return [Integer] The unique identifier of the organization the contact belongs to. The field will be set only if the contact is an individual.
23
+ # attr_accessor :contact_id
24
+ # @!attribute [rw] custom_fields
25
+ # @return [Hash] Custom fields are a key-value pair attached to a contact. See more at [Custom Fields](/docs/rest/articles/requests#custom_fields).
26
+ # attr_accessor :custom_fields
27
+ # @!attribute [rw] customer_status
28
+ # @return [String] The customer status of the contact.
29
+ # attr_accessor :customer_status
30
+ # @!attribute [rw] description
31
+ # @return [String] The contact's description.
32
+ # attr_accessor :description
33
+ # @!attribute [rw] email
34
+ # @return [String] The contact's email address.
35
+ # attr_accessor :email
36
+ # @!attribute [rw] facebook
37
+ # @return [String] The contact's Facebook nickname.
38
+ # attr_accessor :facebook
39
+ # @!attribute [rw] fax
40
+ # @return [String] The contact's fax number.
41
+ # attr_accessor :fax
42
+ # @!attribute [rw] first_name
43
+ # @return [String] First name of the contact.
44
+ # attr_accessor :first_name
45
+ # @!attribute [rw] industry
46
+ # @return [String] The contact's industry.
47
+ # attr_accessor :industry
48
+ # @!attribute [rw] is_organization
49
+ # @return [Boolean] Indicator of whether or not this contact refers to an organization or an individual. This value can be set **only** during creation and **cannot** be changed later. The default value is `false`.
50
+ # attr_accessor :is_organization
51
+ # @!attribute [rw] last_name
52
+ # @return [String] Last name of the contact. Required only if the contact is an individual.
53
+ # attr_accessor :last_name
54
+ # @!attribute [rw] linkedin
55
+ # @return [String] The contact's Linkedin nickname.
56
+ # attr_accessor :linkedin
57
+ # @!attribute [rw] mobile
58
+ # @return [String] The contact's mobile phone number.
59
+ # attr_accessor :mobile
60
+ # @!attribute [rw] name
61
+ # @return [String] Name of the contact. Required only if the contact is an organization.
62
+ # attr_accessor :name
63
+ # @!attribute [rw] owner_id
64
+ # @return [Integer] The unique identifier of the user the contact is currently assigned to.
65
+ # attr_accessor :owner_id
66
+ # @!attribute [rw] phone
67
+ # @return [String] The contact's phone number.
68
+ # attr_accessor :phone
69
+ # @!attribute [rw] prospect_status
70
+ # @return [String] The prospect status of the contact.
71
+ # attr_accessor :prospect_status
72
+ # @!attribute [rw] skype
73
+ # @return [String] The contact's Skype nickname.
74
+ # attr_accessor :skype
75
+ # @!attribute [rw] tags
76
+ # @return [Array<String>] An array of tags for the contact. See more at [Tags](/docs/rest/articles/requests#tags).
77
+ # attr_accessor :tags
78
+ # @!attribute [rw] title
79
+ # @return [String] The contact's job title.
80
+ # attr_accessor :title
81
+ # @!attribute [rw] twitter
82
+ # @return [String] The contact's Twitter handle.
83
+ # attr_accessor :twitter
84
+ # @!attribute [rw] website
85
+ # @return [String] The contact's website address.
86
+ # attr_accessor :website
87
+ end
88
+ end