close 0.1.0 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +4 -0
- data/Gemfile.lock +25 -1
- data/README.md +26 -2
- data/close-0.1.0.gem +0 -0
- data/close-0.1.1.gem +0 -0
- data/lib/close/data/filters/find_lead_by_contact_email.json +60 -0
- data/lib/close/errors.rb +2 -0
- data/lib/close/filter.rb +99 -0
- data/lib/close/version.rb +1 -1
- data/lib/close.rb +1 -0
- metadata +9 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4ae57ff51e41efeb5bcf5464bca8b5e23a6388806e71fc73378d389be7d652a1
|
4
|
+
data.tar.gz: 61eec10200545f071801b978090b9c43e8608e2dc3230207ecbe07bb903106ce
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 84e59c4ef43627a67343d39f93ef6cf888aa5c038dfa54ee65d23ee3d38d54422788ce44ea6b8b9410e57a0a4bcb7527671d3ef20a5723232895127c177b8509
|
7
|
+
data.tar.gz: 776e2d4bedb0051203e458e200ee6e45b016904dbb3d1b6cdaf180988bd3c482ff43408eb981c678389cc1db1cdefd8f2d9dd1cb25a16f8e724a64484bd06a34
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,24 +1,35 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
close (0.1.
|
4
|
+
close (0.1.1)
|
5
5
|
faraday
|
6
6
|
ostruct
|
7
7
|
|
8
8
|
GEM
|
9
9
|
remote: https://rubygems.org/
|
10
10
|
specs:
|
11
|
+
addressable (2.8.1)
|
12
|
+
public_suffix (>= 2.0.2, < 6.0)
|
11
13
|
ast (2.4.2)
|
14
|
+
crack (0.4.5)
|
15
|
+
rexml
|
12
16
|
diff-lcs (1.5.0)
|
13
17
|
faraday (2.6.0)
|
14
18
|
faraday-net_http (>= 2.0, < 3.1)
|
15
19
|
ruby2_keywords (>= 0.0.4)
|
16
20
|
faraday-net_http (3.0.1)
|
21
|
+
hashdiff (1.0.1)
|
17
22
|
json (2.6.2)
|
23
|
+
mustermann (3.0.0)
|
24
|
+
ruby2_keywords (~> 0.0.1)
|
18
25
|
ostruct (0.5.5)
|
19
26
|
parallel (1.22.1)
|
20
27
|
parser (3.1.2.1)
|
21
28
|
ast (~> 2.4.1)
|
29
|
+
public_suffix (5.0.0)
|
30
|
+
rack (2.2.4)
|
31
|
+
rack-protection (3.0.2)
|
32
|
+
rack
|
22
33
|
rainbow (3.1.1)
|
23
34
|
rake (13.0.6)
|
24
35
|
regexp_parser (2.6.0)
|
@@ -50,10 +61,21 @@ GEM
|
|
50
61
|
parser (>= 3.1.1.0)
|
51
62
|
ruby-progressbar (1.11.0)
|
52
63
|
ruby2_keywords (0.0.5)
|
64
|
+
sinatra (3.0.2)
|
65
|
+
mustermann (~> 3.0)
|
66
|
+
rack (~> 2.2, >= 2.2.4)
|
67
|
+
rack-protection (= 3.0.2)
|
68
|
+
tilt (~> 2.0)
|
69
|
+
tilt (2.0.11)
|
53
70
|
unicode-display_width (2.3.0)
|
71
|
+
webmock (3.18.1)
|
72
|
+
addressable (>= 2.8.0)
|
73
|
+
crack (>= 0.3.2)
|
74
|
+
hashdiff (>= 0.4.0, < 2.0.0)
|
54
75
|
|
55
76
|
PLATFORMS
|
56
77
|
arm64-darwin-21
|
78
|
+
ruby
|
57
79
|
|
58
80
|
DEPENDENCIES
|
59
81
|
close!
|
@@ -61,6 +83,8 @@ DEPENDENCIES
|
|
61
83
|
rake (~> 13.0)
|
62
84
|
rspec (~> 3.0)
|
63
85
|
rubocop (~> 1.21)
|
86
|
+
sinatra
|
87
|
+
webmock
|
64
88
|
|
65
89
|
BUNDLED WITH
|
66
90
|
2.3.7
|
data/README.md
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# Close
|
2
2
|
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/close.svg)](https://badge.fury.io/rb/close) [![Test Coverage](https://api.codeclimate.com/v1/badges/d83380e81bfb459ea027/test_coverage)](https://codeclimate.com/github/joynerd/close/test_coverage)
|
4
|
+
|
3
5
|
This a ruby gem that provides a robust way to interact with the Close
|
4
6
|
CRM API.
|
5
7
|
|
@@ -59,17 +61,39 @@ leads = Close::Lead.list
|
|
59
61
|
# Get a single lead
|
60
62
|
lead = Close::Lead.retrieve('lead_id')
|
61
63
|
|
62
|
-
# Update the name
|
64
|
+
# Update the name (and other attributes) of a lead. These are not persisted to the API until you call save.
|
63
65
|
lead.name = 'New Name'
|
64
66
|
|
65
67
|
# Save the changes
|
66
68
|
lead.save
|
67
69
|
|
68
|
-
|
69
70
|
```
|
70
71
|
|
71
72
|
## Supported Resources
|
72
73
|
|
74
|
+
### Advanced Filters
|
75
|
+
[Close API Docs](https://developer.close.com/resources/leads/)
|
76
|
+
|
77
|
+
Advanced Filters are a clever way to open up search to the API, with the caveat that they are very dense and appear to be written in search DSL (Elastic, Solr, etc).
|
78
|
+
|
79
|
+
I have tried to encapsulate the complexity of the DSL into a simple interface that is easy to use. This is mostly by defining queries before
|
80
|
+
they are run and then running them with parameters when they are needed.
|
81
|
+
|
82
|
+
An example of an advanced filter query:
|
83
|
+
|
84
|
+
```ruby
|
85
|
+
# Run a prebuilt query
|
86
|
+
Close::AdvancedFilter.run('find_leads_by_email', {email: 'buster.bluth@gmail.com'})
|
87
|
+
|
88
|
+
# Add a new query
|
89
|
+
Close::AdvancedFilter.add('find_leads_by_phone_number', {phone_number: '%PHONE_NUMBER%'})
|
90
|
+
|
91
|
+
# Run the new query
|
92
|
+
Close::AdvancedFilter.run('find_leads_by_phone_number', {phone_number: '555-555-5555'})
|
93
|
+
```
|
94
|
+
|
95
|
+
If you think you have a common query or one that would be useful to others, please open an issue with a new query and I will add it to the gem. Or you can submit a PR with the JSON for the query added to the repo.
|
96
|
+
|
73
97
|
### Leads
|
74
98
|
[Close API Docs](https://developer.close.com/resources/leads/)
|
75
99
|
|
data/close-0.1.0.gem
ADDED
Binary file
|
data/close-0.1.1.gem
ADDED
Binary file
|
@@ -0,0 +1,60 @@
|
|
1
|
+
{
|
2
|
+
"limit": null,
|
3
|
+
"query": {
|
4
|
+
"negate": false,
|
5
|
+
"queries": [
|
6
|
+
{
|
7
|
+
"negate": false,
|
8
|
+
"object_type": "lead",
|
9
|
+
"type": "object_type"
|
10
|
+
},
|
11
|
+
{
|
12
|
+
"negate": false,
|
13
|
+
"queries": [
|
14
|
+
{
|
15
|
+
"negate": false,
|
16
|
+
"related_object_type": "contact",
|
17
|
+
"related_query": {
|
18
|
+
"negate": false,
|
19
|
+
"queries": [
|
20
|
+
{
|
21
|
+
"negate": false,
|
22
|
+
"related_object_type": "contact_email",
|
23
|
+
"related_query": {
|
24
|
+
"negate": false,
|
25
|
+
"queries": [
|
26
|
+
{
|
27
|
+
"condition": {
|
28
|
+
"mode": "full_words",
|
29
|
+
"type": "text",
|
30
|
+
"value": "%EMAIL%"
|
31
|
+
},
|
32
|
+
"field": {
|
33
|
+
"field_name": "email",
|
34
|
+
"object_type": "contact_email",
|
35
|
+
"type": "regular_field"
|
36
|
+
},
|
37
|
+
"negate": false,
|
38
|
+
"type": "field_condition"
|
39
|
+
}
|
40
|
+
],
|
41
|
+
"type": "and"
|
42
|
+
},
|
43
|
+
"this_object_type": "contact",
|
44
|
+
"type": "has_related"
|
45
|
+
}
|
46
|
+
],
|
47
|
+
"type": "and"
|
48
|
+
},
|
49
|
+
"this_object_type": "lead",
|
50
|
+
"type": "has_related"
|
51
|
+
}
|
52
|
+
],
|
53
|
+
"type": "and"
|
54
|
+
}
|
55
|
+
],
|
56
|
+
"type": "and"
|
57
|
+
},
|
58
|
+
"results_limit": null,
|
59
|
+
"sort": []
|
60
|
+
}
|
data/lib/close/errors.rb
CHANGED
data/lib/close/filter.rb
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
# This class attempts to abstract away the Advanced Filter API.
|
2
|
+
# It is very powerful and fast, but building the queries is very tedious.
|
3
|
+
# It allows to store preset queries as JSON for common queries that
|
4
|
+
# can be commited to the repo and validated. It also lets you
|
5
|
+
# define queries on the fly which can then be reused across the
|
6
|
+
# codebase without having to copy and paste the query all the time.
|
7
|
+
module Close
|
8
|
+
class Filter
|
9
|
+
extend APIOperations
|
10
|
+
|
11
|
+
@@queries = {}
|
12
|
+
|
13
|
+
# Executes a raw query against the Close API.
|
14
|
+
# @param [Hash] query The query to execute.
|
15
|
+
# @return [Array] An array of results.
|
16
|
+
def self.execute(query = {})
|
17
|
+
response = request(:post, 'api/v1/data/search/', query)
|
18
|
+
response['data']
|
19
|
+
end
|
20
|
+
|
21
|
+
# Executes a query by name.
|
22
|
+
# @param [String] name The name of the query to execute.
|
23
|
+
# @param [Hash] params The parameters to pass to the query.
|
24
|
+
# @return [Array] An array of results.
|
25
|
+
def self.run(name, params = {})
|
26
|
+
query_string = load_query_from_file(name)
|
27
|
+
expected_params = find_params(query_string)
|
28
|
+
preflight_params(params, expected_params)
|
29
|
+
parameterized_query = apply_params(query_string, params)
|
30
|
+
execute(parameterized_query)
|
31
|
+
end
|
32
|
+
|
33
|
+
# Loads a query from a file or from memory.
|
34
|
+
# @param [String] name The name of the query.
|
35
|
+
# @return [String] A stringified JSON query.
|
36
|
+
def self.load_query(name)
|
37
|
+
if @@queries[name.to_s]
|
38
|
+
@@queries[name.to_s]
|
39
|
+
else
|
40
|
+
load_query_from_file(name)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# This method is used to defined a query at run time.
|
45
|
+
# If a name collision occurs, the query will be overwritten.
|
46
|
+
# @param [String] name The name of the query.
|
47
|
+
# @param [Hash] query_body A hash with placeholders in keys.
|
48
|
+
# @return [Void]
|
49
|
+
def self.add_query(name, query_body)
|
50
|
+
@@queries[name.to_s] = query_body.to_json
|
51
|
+
end
|
52
|
+
|
53
|
+
# Applies the params to the query string.
|
54
|
+
# @param [String] query_string The stringified JSON query.
|
55
|
+
# @param [Hash] params The parameters to apply.
|
56
|
+
# @return [String] The stringified JSON query with the parameters applied.
|
57
|
+
def self.apply_params(query_string, params)
|
58
|
+
qs = query_string.dup
|
59
|
+
params.each do |key, value|
|
60
|
+
qs.gsub!(/%#{key.upcase}%/, value)
|
61
|
+
end
|
62
|
+
qs
|
63
|
+
end
|
64
|
+
|
65
|
+
# Check that all of the params are present in expected_params.
|
66
|
+
# @param [Hash] params The parameters to check.
|
67
|
+
# @param [Array] expected_params The expected parameters.
|
68
|
+
# @return [Void]
|
69
|
+
# @raise [Close::MissingParameterError] if a parameter is missing.
|
70
|
+
def self.preflight_params(params, expected_params)
|
71
|
+
expected_params.each do |param|
|
72
|
+
if !params.transform_keys(&:to_s).has_key?(param.to_s)
|
73
|
+
raise Close::MissingParameterError, "Missing parameter: #{param}"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# Loads a predefined query from a file.
|
79
|
+
# @param [String] name The name of the query.
|
80
|
+
# @return [String] A stringified JSON query.
|
81
|
+
# @raise [Close::QueryNotFoundError] if the file does not exist.
|
82
|
+
def self.load_query_from_file(name)
|
83
|
+
begin
|
84
|
+
file = File.read("lib/close/data/filters/#{name}.json")
|
85
|
+
rescue Errno::ENOENT
|
86
|
+
raise Close::QueryNotFoundError.new("Query #{name} not found.")
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
# Scans a string a returns the parameters it will expect
|
91
|
+
# when executed.
|
92
|
+
# @param [String] str The string to scan.
|
93
|
+
# @return [Array] An array of parameters.
|
94
|
+
def self.find_params(str)
|
95
|
+
str.scan(/%[A-Z]+(?:_[A-Z]+)*%/).map{ |x| x[1..-2].downcase }.uniq
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
end
|
data/lib/close/version.rb
CHANGED
data/lib/close.rb
CHANGED
@@ -5,6 +5,7 @@ require "faraday"
|
|
5
5
|
require_relative "close/close_object"
|
6
6
|
require_relative "close/api_operations"
|
7
7
|
require_relative "close/api_resource"
|
8
|
+
require_relative "close/filter"
|
8
9
|
require_relative "close/resources"
|
9
10
|
require_relative "close/errors"
|
10
11
|
require_relative "close/version"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: close
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- JoyNerd LLC
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-10-
|
11
|
+
date: 2022-10-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ostruct
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
33
|
+
version: 2.0.0
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
40
|
+
version: 2.0.0
|
41
41
|
description: A ruby wrapper for the close.com API that offers caching.
|
42
42
|
email:
|
43
43
|
- developers@joynerd.io
|
@@ -54,11 +54,15 @@ files:
|
|
54
54
|
- LICENSE.txt
|
55
55
|
- README.md
|
56
56
|
- Rakefile
|
57
|
+
- close-0.1.0.gem
|
58
|
+
- close-0.1.1.gem
|
57
59
|
- lib/close.rb
|
58
60
|
- lib/close/api_operations.rb
|
59
61
|
- lib/close/api_resource.rb
|
60
62
|
- lib/close/close_object.rb
|
63
|
+
- lib/close/data/filters/find_lead_by_contact_email.json
|
61
64
|
- lib/close/errors.rb
|
65
|
+
- lib/close/filter.rb
|
62
66
|
- lib/close/resource/contact.rb
|
63
67
|
- lib/close/resource/custom_activity_type.rb
|
64
68
|
- lib/close/resource/lead.rb
|
@@ -89,7 +93,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
89
93
|
- !ruby/object:Gem::Version
|
90
94
|
version: '0'
|
91
95
|
requirements: []
|
92
|
-
rubygems_version: 3.
|
96
|
+
rubygems_version: 3.0.9
|
93
97
|
signing_key:
|
94
98
|
specification_version: 4
|
95
99
|
summary: A ruby wrapper for the close.com API
|