close 0.1.0 → 0.1.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 +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
|