basecrm 0.1.2 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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