pipe_rocket 0.0.1

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 794070337cc9ed25712f6ec80fa6d541ca7d9af7bff8ff58003b8aba0c82c130
4
+ data.tar.gz: e04b4494afe552d89ed7f4bcaf4cd914a7828c9351649f286907e067fefbb02e
5
+ SHA512:
6
+ metadata.gz: 8002c294465b23428b1d79f8ca457a54428ed035463be531730c41b67494b06a410e2531b9afbe255785cdccc0224e4356213ba90d7766f14c106c96a3a0945b
7
+ data.tar.gz: 459b00f198b5a96d82f81e61bcf801833620a38d3aafdc44026304a584ff775347fd70e2aae14ded6d7a7f4533dac530a68577a91b337366268bcd2dfcd30660
@@ -0,0 +1,8 @@
1
+ module PipeRocket
2
+ class EventsController < ApplicationController
3
+ skip_before_action :verify_authenticity_token
4
+ def handle
5
+ ActiveSupport::Notifications.instrument "#{params[:object]}_#{params[:event]}", {params[:object].to_sym => "PipeRocket::#{params[:object].titleize}".constantize.new(params[:current])}
6
+ end
7
+ end
8
+ end
data/config/routes.rb ADDED
@@ -0,0 +1,5 @@
1
+ Rails.application.routes.draw do
2
+ scope '/pipedrive' do
3
+ post '/:object/:event' => 'pipe_rocket/events#handle'
4
+ end
5
+ end
@@ -0,0 +1,50 @@
1
+ require 'pipe_rocket/organization'
2
+ require 'pipe_rocket/person'
3
+
4
+ module PipeRocket
5
+ class Deal < Entity
6
+ attr_accessor :organization, :person
7
+ def self.key_field_hash
8
+ @@key_field_hash ||= Pipedrive.deal_fields.key_field_hash
9
+ end
10
+
11
+ def initialize(hash)
12
+ super(hash.except(*Deal.key_field_hash.keys))
13
+
14
+ org_id = hash['org_id']
15
+ person_id = hash['person_id']
16
+
17
+ assign_custom_fields(Deal.key_field_hash, hash)
18
+
19
+ if org_id
20
+ @organization = case org_id
21
+ when Integer
22
+ Pipedrive.organizations.find(org_id)
23
+ when Hash
24
+ Organization.new(org_id)
25
+ else
26
+ nil
27
+ end
28
+ end
29
+
30
+ if person_id
31
+ @person = case person_id
32
+ when Integer
33
+ Pipedrive.persons.find(person_id)
34
+ when Hash
35
+ Person.new(person_id)
36
+ else
37
+ nil
38
+ end
39
+ end
40
+ end
41
+
42
+ def stage
43
+ Pipedrive.stages.find(self.stage_id)
44
+ end
45
+
46
+ def display_stage_name
47
+ self.stage.display_name
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,4 @@
1
+ module PipeRocket
2
+ class DealField < Field
3
+ end
4
+ end
@@ -0,0 +1,5 @@
1
+ module PipeRocket
2
+ class Engine < Rails::Engine
3
+ isolate_namespace PipeRocket
4
+ end
5
+ end
@@ -0,0 +1,38 @@
1
+ module PipeRocket
2
+ class Entity
3
+ def initialize(hash)
4
+ hash.each do |k,v|
5
+ if k[0] =~ /[a-zA-Z_]/
6
+ instance_variable_set("@#{k}",v)
7
+ self.class.class_eval {attr_accessor k}
8
+ end
9
+ end
10
+ end
11
+
12
+ def assign_custom_fields(key_name_hash, entity_hash)
13
+ names = key_name_hash.map do |key, field|
14
+ name = field.name
15
+ name = name.underscore.gsub(' ','_')
16
+ name = name.gsub('%','percent').gsub(/[^a-zA-Z0-9_]/,'')
17
+ name = transform_field_name(key, name)
18
+ if field.field_type == 'enum'
19
+ option_id = entity_hash[key]
20
+ res_field = field.dup
21
+ res_field.option_id = option_id
22
+ instance_variable_set("@#{name}", res_field)
23
+ else
24
+ instance_variable_set("@#{name}", entity_hash[key])
25
+ end
26
+ name
27
+ end
28
+ self.class.class_eval {attr_accessor *names}
29
+ end
30
+
31
+ def transform_field_name(key, name)
32
+ hash = ::CUSTOM_FIELD_NAMES
33
+ class_name = self.class.name.demodulize.underscore.to_sym
34
+ return name if hash.nil? || hash[class_name].nil? || hash[class_name][key.to_sym].nil?
35
+ hash[class_name][key.to_sym]
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,8 @@
1
+ module PipeRocket
2
+ class Error < StandardError
3
+ attr_accessor :code
4
+ def initialize(code)
5
+ @code = code
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,18 @@
1
+ module PipeRocket
2
+ class Field < Entity
3
+ attr_accessor :is_subfield, :option_id
4
+ def initialize(hash)
5
+ super
6
+ @is_subfield ||= false
7
+ end
8
+
9
+ def options_hash
10
+ return {} unless @options
11
+ @options.map{|option|{option['id'].to_s => option['label']}}.inject(:merge)
12
+ end
13
+
14
+ def value
15
+ options_hash[option_id]
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,21 @@
1
+ module PipeRocket
2
+ class FieldService < Service
3
+ HOST = 'https://api.pipedrive.com/v1'
4
+
5
+ def initialize(resource_name)
6
+ @resource_name = resource_name
7
+ end
8
+
9
+ def key_field_hash
10
+ Pipedrive.send("#{@resource_name.split(/(?=[A-Z])/).first}_fields").all.select{|field|field.edit_flag || field.is_subfield}.map{|field|{field.key => field}}.inject(:merge) || {}
11
+ end
12
+
13
+ def key_name_hash
14
+ Pipedrive.send("#{@resource_name.split(/(?=[A-Z])/).first}_fields").all.select{|field|field.edit_flag || field.is_subfield}.map{|field|{field.key => field.name}}.inject(:merge) || {}
15
+ end
16
+
17
+ def name_key_hash
18
+ Pipedrive.send("#{@resource_name.split(/(?=[A-Z])/).first}_fields").all.select{|field|field.edit_flag || field.is_subfield}.map{|field|{field.name => field.key}}.inject(:merge) || {}
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,4 @@
1
+ module PipeRocket
2
+ class Note < Entity
3
+ end
4
+ end
@@ -0,0 +1,13 @@
1
+ module PipeRocket
2
+ class Organization < Entity
3
+ def self.key_field_hash
4
+ @@key_field_hash ||= Pipedrive.organization_fields.key_field_hash
5
+ end
6
+
7
+ def initialize(hash)
8
+ super(hash.except(*Organization.key_field_hash.keys))
9
+ @id = hash['value'] if hash['value'].present?
10
+ assign_custom_fields(Organization.key_field_hash, hash)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,4 @@
1
+ module PipeRocket
2
+ class OrganizationField < Field
3
+ end
4
+ end
@@ -0,0 +1,30 @@
1
+ module PipeRocket
2
+ class Person < Entity
3
+ attr_accessor :email, :phone, :organization, :id
4
+
5
+ def self.key_field_hash
6
+ @@key_field_hash ||= Pipedrive.person_fields.key_field_hash
7
+ end
8
+
9
+ def initialize(hash)
10
+ super(hash.except(*Person.key_field_hash.keys))
11
+ @email = hash['email'].first['value'] if hash['email']
12
+ @phone = hash['phone'].first['value'] if hash['phone']
13
+ @id = hash['value'] if hash['value'].present?
14
+
15
+ assign_custom_fields(Person.key_field_hash, hash)
16
+
17
+ org_id = hash['org_id']
18
+ if org_id
19
+ @organization = case org_id
20
+ when Integer
21
+ Pipedrive.organizations.find(org_id)
22
+ when Hash
23
+ Organization.new(org_id)
24
+ else
25
+ nil
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,4 @@
1
+ module PipeRocket
2
+ class PersonField < Field
3
+ end
4
+ end
@@ -0,0 +1,26 @@
1
+ module PipeRocket
2
+ class PersonService < Service
3
+ HOST = 'https://api.pipedrive.com/v1'
4
+
5
+ def initialize(resource_name)
6
+ @resource_name = resource_name
7
+ end
8
+
9
+ def find_by_email(email)
10
+ uri = build_uri({term: email, search_by_email: true }, 'find')
11
+ response = HTTP.get(uri)
12
+
13
+ case response.code
14
+ when 200
15
+ json_array = ::JSON.parse(response)['data']
16
+ return [] unless json_array
17
+ json_array.map{|raw|build_entity(raw)}
18
+ else
19
+ raise PipeRocket::Error.new(response.code)
20
+ end
21
+ rescue HTTP::ConnectionError
22
+ raise PipeRocket::Error.new(408)
23
+ end
24
+
25
+ end
26
+ end
@@ -0,0 +1,4 @@
1
+ module PipeRocket
2
+ class Pipeline < Entity
3
+ end
4
+ end
@@ -0,0 +1,136 @@
1
+ require 'http'
2
+ require 'pipe_rocket/deal'
3
+ require 'pipe_rocket/deal_field'
4
+ require 'pipe_rocket/note'
5
+ require 'pipe_rocket/organization'
6
+ require 'pipe_rocket/organization_field'
7
+ require 'pipe_rocket/person'
8
+ require 'pipe_rocket/person_field'
9
+ require 'pipe_rocket/pipeline'
10
+ require 'pipe_rocket/stage'
11
+ require 'pipe_rocket/user'
12
+ require 'pipe_rocket/error'
13
+
14
+ module PipeRocket
15
+ class Service
16
+ HOST = 'https://api.pipedrive.com/v1'
17
+ RESOURCES_WITH_CUSTOM_FIELDS = %w(deal organization person)
18
+
19
+ def initialize(resource_name)
20
+ @resource_name = resource_name
21
+ @has_custom_fields = RESOURCES_WITH_CUSTOM_FIELDS.include?(@resource_name)
22
+ end
23
+
24
+ def build_entity(raw)
25
+ "PipeRocket::#{@resource_name.titleize.delete(' ')}".constantize.new(raw)
26
+ end
27
+
28
+ def build_uri(params = {}, specificator = nil)
29
+ params.merge!(api_token: ENV['pipedrive_api_token'])
30
+ query_string = params.map{|k,v|"#{k}=#{v}"}.join('&')
31
+ plural_resource_name = @resource_name == 'person' ? 'persons' : @resource_name.pluralize
32
+ uri = URI("#{HOST}/#{plural_resource_name}/#{specificator}?#{query_string}")
33
+ end
34
+
35
+ def all
36
+ uri = build_uri
37
+ response = HTTP.get(uri)
38
+
39
+ case response.code
40
+ when 200
41
+ json_array = ::JSON.parse(response)['data']
42
+ json_array.map{|raw|build_entity(raw)}
43
+ else
44
+ raise PipeRocket::Error.new(response.code)
45
+ end
46
+ rescue HTTP::ConnectionError
47
+ raise PipeRocket::Error.new(408)
48
+ end
49
+
50
+ def create(params)
51
+ uri = build_uri
52
+ response = HTTP.post(uri, form: transform_custom_fields(params))
53
+
54
+ case response.code
55
+ when 201
56
+ build_entity(JSON.parse(response.body)['data'])
57
+ else
58
+ raise PipeRocket::Error.new(response.code)
59
+ end
60
+ rescue HTTP::ConnectionError
61
+ raise PipeRocket::Error.new(408)
62
+ end
63
+
64
+ def find(id)
65
+ uri = build_uri({}, id)
66
+ response = HTTP.get(uri)
67
+
68
+ case response.code
69
+ when 200
70
+ raw = ::JSON.parse(response)['data']
71
+ build_entity(raw)
72
+ else
73
+ raise PipeRocket::Error.new(response.code)
74
+ end
75
+ rescue HTTP::ConnectionError
76
+ raise PipeRocket::Error.new(408)
77
+ end
78
+
79
+ def first
80
+ self.all.first
81
+ end
82
+
83
+ def update(id, params)
84
+ uri = build_uri({}, id)
85
+ response = HTTP.put(uri, form: transform_custom_fields(params))
86
+
87
+ case response.code
88
+ when 200
89
+ build_entity(JSON.parse(response.body)['data'])
90
+ else
91
+ raise PipeRocket::Error.new(response.code)
92
+ end
93
+ rescue HTTP::ConnectionError
94
+ raise PipeRocket::Error.new(408)
95
+ end
96
+
97
+ protected
98
+
99
+ def transform_custom_fields(params)
100
+ return params unless @has_custom_fields
101
+
102
+ @@name_key_hash = Pipedrive.send("#{@resource_name}_fields").name_key_hash
103
+ @@name_key_hash.transform_keys!{|key|clear_key(key)}
104
+
105
+ hash = ::CUSTOM_FIELD_NAMES
106
+ if hash && hash[@resource_name.to_sym]
107
+ @@name_key_hash = @@name_key_hash.merge(hash[@resource_name.to_sym].invert)
108
+ end
109
+
110
+ keys = @@name_key_hash.keys
111
+ res = {}
112
+
113
+ params.each do |name, value|
114
+ if keys.include?(name.to_s) #Custom Field
115
+ res[@@name_key_hash[name.to_s]] = value
116
+ else
117
+ res[name] = value
118
+ end
119
+ end
120
+ res
121
+ end
122
+
123
+ def transform_field_name(key, name)
124
+ hash = ::CUSTOM_FIELD_NAMES
125
+ class_name = @resource_name
126
+ return name if hash.nil? || hash[class_name].nil? || hash[class_name].key(key.to_sym).nil?
127
+ hash[class_name][key.to_sym]
128
+ end
129
+
130
+ def clear_key(key)
131
+ key = key.underscore.gsub(' ','_')
132
+ key = key.gsub('%','percent').gsub(/[^a-zA-Z0-9_]/,'')
133
+ end
134
+
135
+ end
136
+ end
@@ -0,0 +1,11 @@
1
+ module PipeRocket
2
+ class Stage < Entity
3
+ def pipeline
4
+ Pipedrive.pipelines.find(self.pipeline_id)
5
+ end
6
+
7
+ def display_name
8
+ "#{pipeline.name}:#{name}"
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,4 @@
1
+ module PipeRocket
2
+ class User < Entity
3
+ end
4
+ end
@@ -0,0 +1,48 @@
1
+ require 'net/http'
2
+ require 'pipe_rocket/entity'
3
+ require 'pipe_rocket/field'
4
+ unless ENV["RAILS_ENV"] == 'test'
5
+ require 'pipe_rocket/engine'
6
+ end
7
+ require 'pipe_rocket/service'
8
+ require 'pipe_rocket/person_service'
9
+ require 'pipe_rocket/field_service'
10
+
11
+ class Pipedrive
12
+
13
+ def self.deals
14
+ @@deals_service ||= PipeRocket::Service.new('deal')
15
+ end
16
+
17
+ def self.deal_fields
18
+ @@deal_fields_service ||= PipeRocket::FieldService.new('dealField')
19
+ end
20
+
21
+ def self.notes
22
+ @@notes_service ||= PipeRocket::Service.new('note')
23
+ end
24
+
25
+ def self.organizations
26
+ @@organizations_service ||= PipeRocket::Service.new('organization')
27
+ end
28
+
29
+ def self.organization_fields
30
+ @@organization_fields ||= PipeRocket::FieldService.new('organizationField')
31
+ end
32
+
33
+ def self.persons
34
+ @@persons_service ||= PipeRocket::PersonService.new('person')
35
+ end
36
+
37
+ def self.person_fields
38
+ @@person_fields ||= PipeRocket::FieldService.new('personField')
39
+ end
40
+
41
+ def self.pipelines
42
+ @@pipelines_service ||= PipeRocket::Service.new('pipeline')
43
+ end
44
+
45
+ def self.stages
46
+ @@stages_service ||= PipeRocket::Service.new('stage')
47
+ end
48
+ end
metadata ADDED
@@ -0,0 +1,77 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pipe_rocket
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Agafonov Maksim
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-01-18 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: http
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ description: Pipedrive API wrapper
28
+ email: agafonov.maksim@jetrockets.ru
29
+ executables: []
30
+ extensions: []
31
+ extra_rdoc_files: []
32
+ files:
33
+ - app/controllers/pipe_rocket/events_controller.rb
34
+ - config/routes.rb
35
+ - lib/pipe_rocket.rb
36
+ - lib/pipe_rocket/deal.rb
37
+ - lib/pipe_rocket/deal_field.rb
38
+ - lib/pipe_rocket/engine.rb
39
+ - lib/pipe_rocket/entity.rb
40
+ - lib/pipe_rocket/error.rb
41
+ - lib/pipe_rocket/field.rb
42
+ - lib/pipe_rocket/field_service.rb
43
+ - lib/pipe_rocket/note.rb
44
+ - lib/pipe_rocket/organization.rb
45
+ - lib/pipe_rocket/organization_field.rb
46
+ - lib/pipe_rocket/person.rb
47
+ - lib/pipe_rocket/person_field.rb
48
+ - lib/pipe_rocket/person_service.rb
49
+ - lib/pipe_rocket/pipeline.rb
50
+ - lib/pipe_rocket/service.rb
51
+ - lib/pipe_rocket/stage.rb
52
+ - lib/pipe_rocket/user.rb
53
+ homepage: https://github.com/agafonovmak/pipe_rocket/
54
+ licenses:
55
+ - MIT
56
+ metadata: {}
57
+ post_install_message:
58
+ rdoc_options: []
59
+ require_paths:
60
+ - lib
61
+ required_ruby_version: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ required_rubygems_version: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ requirements: []
72
+ rubyforge_project:
73
+ rubygems_version: 2.7.6
74
+ signing_key:
75
+ specification_version: 4
76
+ summary: Pipedrive API wrapper
77
+ test_files: []