pipe_rocket 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/app/controllers/pipe_rocket/events_controller.rb +8 -0
- data/config/routes.rb +5 -0
- data/lib/pipe_rocket/deal.rb +50 -0
- data/lib/pipe_rocket/deal_field.rb +4 -0
- data/lib/pipe_rocket/engine.rb +5 -0
- data/lib/pipe_rocket/entity.rb +38 -0
- data/lib/pipe_rocket/error.rb +8 -0
- data/lib/pipe_rocket/field.rb +18 -0
- data/lib/pipe_rocket/field_service.rb +21 -0
- data/lib/pipe_rocket/note.rb +4 -0
- data/lib/pipe_rocket/organization.rb +13 -0
- data/lib/pipe_rocket/organization_field.rb +4 -0
- data/lib/pipe_rocket/person.rb +30 -0
- data/lib/pipe_rocket/person_field.rb +4 -0
- data/lib/pipe_rocket/person_service.rb +26 -0
- data/lib/pipe_rocket/pipeline.rb +4 -0
- data/lib/pipe_rocket/service.rb +136 -0
- data/lib/pipe_rocket/stage.rb +11 -0
- data/lib/pipe_rocket/user.rb +4 -0
- data/lib/pipe_rocket.rb +48 -0
- metadata +77 -0
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,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,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,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,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,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,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,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
|
data/lib/pipe_rocket.rb
ADDED
@@ -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: []
|