pipe_rocket 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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: []