close 0.1.0 → 0.1.1
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 +23 -0
- data/README.md +17 -0
- data/close-0.1.0.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 +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2854258a74b425cbfcde648007a00465eebb1c42b41ea3dcb5dd8b9af558839e
|
4
|
+
data.tar.gz: e1032fe4a32b4927b50d1aedf0bbfb6eb85b8af6e81f20a04fa77141f77f9ace
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5506272793581e06aee3d9ca3f7302f512436978aaab7e9826dc8c68cedd2d91165a24dcff21ce549af48d05151e68b83930aea5e93679c7142ef7d37c788186
|
7
|
+
data.tar.gz: 815914f77867cbe2152eb143ffe4ace620b297ed0a0283512d324c55ae2520564138c26043ccb2e229cae735980801e61864de7664ceccf3d704f34dcad7ff8f
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -8,17 +8,28 @@ PATH
|
|
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,7 +61,17 @@ 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
|
@@ -61,6 +82,8 @@ DEPENDENCIES
|
|
61
82
|
rake (~> 13.0)
|
62
83
|
rspec (~> 3.0)
|
63
84
|
rubocop (~> 1.21)
|
85
|
+
sinatra
|
86
|
+
webmock
|
64
87
|
|
65
88
|
BUNDLED WITH
|
66
89
|
2.3.7
|
data/README.md
CHANGED
@@ -70,6 +70,23 @@ lead.save
|
|
70
70
|
|
71
71
|
## Supported Resources
|
72
72
|
|
73
|
+
### Advanced Filters
|
74
|
+
[Close API Docs](https://developer.close.com/resources/leads/)
|
75
|
+
|
76
|
+
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).
|
77
|
+
|
78
|
+
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
|
79
|
+
they are run and then running them with parameters when they are needed.
|
80
|
+
|
81
|
+
An example of an advanced filter query:
|
82
|
+
|
83
|
+
```ruby
|
84
|
+
# Run a prebuilt query
|
85
|
+
Close::AdvancedFilter.run('find_leads_by_email', {email: 'buster.bluth@gmail.com'})
|
86
|
+
|
87
|
+
|
88
|
+
```
|
89
|
+
|
73
90
|
### Leads
|
74
91
|
[Close API Docs](https://developer.close.com/resources/leads/)
|
75
92
|
|
data/close-0.1.0.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.1
|
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
|
@@ -54,11 +54,14 @@ files:
|
|
54
54
|
- LICENSE.txt
|
55
55
|
- README.md
|
56
56
|
- Rakefile
|
57
|
+
- close-0.1.0.gem
|
57
58
|
- lib/close.rb
|
58
59
|
- lib/close/api_operations.rb
|
59
60
|
- lib/close/api_resource.rb
|
60
61
|
- lib/close/close_object.rb
|
62
|
+
- lib/close/data/filters/find_lead_by_contact_email.json
|
61
63
|
- lib/close/errors.rb
|
64
|
+
- lib/close/filter.rb
|
62
65
|
- lib/close/resource/contact.rb
|
63
66
|
- lib/close/resource/custom_activity_type.rb
|
64
67
|
- lib/close/resource/lead.rb
|