qube_sync 0.1.3 → 0.2.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/README.md +33 -12
- data/lib/qube_sync/request_builder.rb +49 -0
- data/lib/qube_sync/version.rb +1 -1
- data/lib/qube_sync.rb +8 -4
- metadata +4 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b2c9e1ca88def822a5954628f1b5d336eab0f3e8ba210871c91abc29cc626b93
|
4
|
+
data.tar.gz: eb86ac186eeba798fe0eeeb18179bedf4e83eedca1906a359f5a6ee17d1f0940
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b50b747fff6d9ccfeb7914e63d689fe62479166e71cbe8fed086da10b973e5a96427d54a432513bbd6b3a05f923897c11e29108c9493458fd31a0210d1e2b571
|
7
|
+
data.tar.gz: 74486d4d0f6ca5da0c3521bcb01407d4fc9b32a7e76dce69784bccc5b8dc96ed966d13e0ccb12366d1ff1a78608587a09f5d33877fd48320c0f65b349ad2550a
|
data/README.md
CHANGED
@@ -27,10 +27,6 @@ require 'qube_sync'
|
|
27
27
|
connection_id = QubeSync.create_connection # creates a connection in QUBE on behalf of your user
|
28
28
|
#=> "636d4750-0b07-45f6-a030-e3919c5741ff"
|
29
29
|
|
30
|
-
# You can also pass a block to create_connection as a success callback
|
31
|
-
QubeSync.create_connection do |connection_id|
|
32
|
-
QubeConnection.create!(qube_id: connection_id) # save the connection_id to your database
|
33
|
-
end
|
34
30
|
|
35
31
|
QubeSync.delete_connection("asdf-qwer-asdf-zxcv") # deletes the connection in QUBE
|
36
32
|
#=> true
|
@@ -44,8 +40,20 @@ QubeSync.generate_password(connection_id)
|
|
44
40
|
QubeSync.get_qwc(connection_id)
|
45
41
|
# "<?xml version=\"1.0\"?>\n<QBWCXML>...</QBWCXML>\n"
|
46
42
|
|
43
|
+
# Using the RequestBuilder to build a Quickbooks Request (generates JSON for QubeSync to translate)
|
44
|
+
request_json = QubeSync::RequestBuilder.new do |b|
|
45
|
+
b.QBXML {
|
46
|
+
b.QBXMLMsgsRq(onError: "stopOnError") {
|
47
|
+
b.CustomerQueryRq(requestID: 1) {
|
48
|
+
b.MaxReturned(10)
|
49
|
+
}
|
50
|
+
}
|
51
|
+
}
|
52
|
+
end
|
47
53
|
|
54
|
+
QubeSync.queue_request(connection_id, {request_json: request_json, webhook_url: "myapp.com/webhook"})
|
48
55
|
|
56
|
+
# Using XML directly
|
49
57
|
request_xml = <<~XML
|
50
58
|
<?xml version="1.0"?>
|
51
59
|
<?qbxml version="16.0"?>
|
@@ -58,7 +66,7 @@ request_xml = <<~XML
|
|
58
66
|
</QBXML>
|
59
67
|
XML
|
60
68
|
|
61
|
-
QubeSync.queue_request(connection_id, request_xml, webhook_url
|
69
|
+
QubeSync.queue_request(connection_id, {request_xml: request_xml, webhook_url: "myapp.com/webhook"})
|
62
70
|
#=> {"id"=>"d401228f-06d4-4981-95d8-bb735c0a2c76",
|
63
71
|
# "state"=>"waiting",
|
64
72
|
# "response_xml"=>nil,
|
@@ -69,13 +77,25 @@ QubeSync.queue_request(connection_id, request_xml, webhook_url = "myapp.com/webh
|
|
69
77
|
request_id = _.fetch("id")
|
70
78
|
|
71
79
|
QubeSync.get_request(request_id)
|
72
|
-
#=> {"id"=>"d401228f-06d4-4981-95d8-bb735c0a2c76",
|
73
|
-
# "state"=>"webhook_succeeded",
|
74
|
-
# "response_xml"=>
|
75
|
-
#
|
76
|
-
# "
|
77
|
-
#
|
78
|
-
#
|
80
|
+
#=> {"id" => "d401228f-06d4-4981-95d8-bb735c0a2c76",
|
81
|
+
# "state" => "webhook_succeeded",
|
82
|
+
# "response_xml" =>
|
83
|
+
# "<?xml version=\"1.0\" ?> <QBXML> <QBXMLMsgsRs> ... </QBXMLMsgsRs> </QBXML>",
|
84
|
+
# "response_json" => [
|
85
|
+
# "CustomerQueryRs" => {
|
86
|
+
# "requestID"=>"1",
|
87
|
+
# "statusCode"=>"0",
|
88
|
+
# "statusSeverity"=>"Info",
|
89
|
+
# "statusMessage"=>"Status Message",
|
90
|
+
# "Results" => [
|
91
|
+
# {"Name"=>"Customer 1", "ListID"=>"123"},
|
92
|
+
# {"Name"=>"Customer 2", "ListID"=>"456"}
|
93
|
+
# ]
|
94
|
+
# },
|
95
|
+
# ],
|
96
|
+
# "webhook_url" => "myapp.com/webhook",
|
97
|
+
# "request_xml" =>
|
98
|
+
# "<?xml version=\"1.0\"?><?qbxml version=\"16.0\"?><QBXML> ... </QBXMLMsgsRq></QBXML>"}}
|
79
99
|
|
80
100
|
QubeSync.get_requests(connection_id)
|
81
101
|
#=> [{"id"=>"d401228f-06d4-4981-95d8-bb735c0a2c76",
|
@@ -93,6 +113,7 @@ QubeSync.verify_and_build_webhook!(request.body.read, request.headers['X-Qube-Si
|
|
93
113
|
#=> {
|
94
114
|
# "id"=>"dd8db40a-5169-477a-b9d5-f1a6e5cc96f9",
|
95
115
|
# "timestamp"=>1738620998,
|
116
|
+
# "response_json"=> {...},
|
96
117
|
# "response_xml"=>
|
97
118
|
# "<?xml version=\"1.0\" ?> <QBXML> <QBXMLMsgsRs> ... </QBXMLMsgsRs> </QBXML>"
|
98
119
|
# }
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module QubeSync
|
2
|
+
class RequestBuilder
|
3
|
+
attr_reader :version, :root
|
4
|
+
|
5
|
+
def initialize(version:, &block)
|
6
|
+
@version = version
|
7
|
+
@stack = []
|
8
|
+
instance_eval(&block) if block_given?
|
9
|
+
end
|
10
|
+
|
11
|
+
def method_missing(tag_name, *args, &block)
|
12
|
+
attributes = args.first.is_a?(Hash) ? args.first : {}
|
13
|
+
text = args.first unless args.first.is_a?(Hash)
|
14
|
+
|
15
|
+
element = {
|
16
|
+
"name" => tag_name.to_s,
|
17
|
+
}
|
18
|
+
element["attributes"] = attributes unless attributes.empty?
|
19
|
+
element["text"] = text if text.is_a?(String) || text.is_a?(Numeric)
|
20
|
+
|
21
|
+
if block_given?
|
22
|
+
element["children"] = []
|
23
|
+
@stack.push(element)
|
24
|
+
instance_eval(&block)
|
25
|
+
@stack.pop
|
26
|
+
end
|
27
|
+
|
28
|
+
if @stack.empty?
|
29
|
+
@root ||= []
|
30
|
+
@root << element
|
31
|
+
else
|
32
|
+
@stack.last["children"] << element
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def as_json
|
37
|
+
{
|
38
|
+
"version" => version,
|
39
|
+
"request" => root
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def root
|
46
|
+
@root || []
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
data/lib/qube_sync/version.rb
CHANGED
data/lib/qube_sync.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require_relative "qube_sync/version"
|
2
|
+
require_relative "qube_sync/request_builder"
|
2
3
|
require "faraday"
|
3
4
|
|
4
5
|
module QubeSync
|
@@ -121,12 +122,15 @@ module QubeSync
|
|
121
122
|
|
122
123
|
|
123
124
|
def extract_signature_meta(header)
|
124
|
-
header.split(',')
|
125
|
+
parts = header.split(',')
|
126
|
+
ts = parts.first
|
127
|
+
signatures = parts[1..-1]
|
125
128
|
{
|
126
129
|
timestamp: ts.split("=").last.to_i,
|
127
130
|
signatures: signatures
|
128
131
|
}
|
129
132
|
end
|
133
|
+
|
130
134
|
|
131
135
|
def default_headers
|
132
136
|
{
|
@@ -152,13 +156,13 @@ module QubeSync
|
|
152
156
|
end
|
153
157
|
|
154
158
|
def verify_and_build_webhook!(body, signature, max_age: 500)
|
155
|
-
extract_signature_meta(signature)
|
159
|
+
meta = extract_signature_meta(signature)
|
156
160
|
|
157
|
-
if timestamp < Time.now.to_i - max_age
|
161
|
+
if meta[:timestamp] < Time.now.to_i - max_age
|
158
162
|
raise StaleWebhookError.new('Timestamp more than #{max_age}ms old. To increase this, pass a different value for max_age.')
|
159
163
|
end
|
160
164
|
|
161
|
-
if signatures.detect { |sig| sign_payload(body) == sig }
|
165
|
+
if meta[:signatures].detect { |sig| sign_payload(body) == sig }
|
162
166
|
JSON.parse(body)
|
163
167
|
else
|
164
168
|
raise InvalidWebhookSignatureError.new("Webhook signature mismatch")
|
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: qube_sync
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Garrett Lancaster
|
8
|
-
autorequire:
|
9
8
|
bindir: exe
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
13
|
name: faraday
|
@@ -38,6 +37,7 @@ files:
|
|
38
37
|
- README.md
|
39
38
|
- Rakefile
|
40
39
|
- lib/qube_sync.rb
|
40
|
+
- lib/qube_sync/request_builder.rb
|
41
41
|
- lib/qube_sync/version.rb
|
42
42
|
- qube_sync.gemspec
|
43
43
|
- sig/qube_sync.rbs
|
@@ -47,7 +47,6 @@ metadata:
|
|
47
47
|
homepage_uri: https://github.com/qubeintegrations/qube_sync_rb
|
48
48
|
source_code_uri: https://github.com/qubeintegrations/qube_sync_rb
|
49
49
|
changelog_uri: https://github.com/qubeintegrations/qube_sync_rb/blob/main/CHANGELOG.md
|
50
|
-
post_install_message:
|
51
50
|
rdoc_options: []
|
52
51
|
require_paths:
|
53
52
|
- lib
|
@@ -62,8 +61,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
62
61
|
- !ruby/object:Gem::Version
|
63
62
|
version: '0'
|
64
63
|
requirements: []
|
65
|
-
rubygems_version: 3.
|
66
|
-
signing_key:
|
64
|
+
rubygems_version: 3.6.9
|
67
65
|
specification_version: 4
|
68
66
|
summary: Ruby library for the QUBE Sync API
|
69
67
|
test_files: []
|