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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f34c269c2f1e3291ae88d68036b9d02eda39da5cc6d5601afba689a2630f8321
4
- data.tar.gz: 2c0c06fffbd1291b0e397365e9e0ac44fe899b47c75f8394f28ffca0ca97db23
3
+ metadata.gz: b2c9e1ca88def822a5954628f1b5d336eab0f3e8ba210871c91abc29cc626b93
4
+ data.tar.gz: eb86ac186eeba798fe0eeeb18179bedf4e83eedca1906a359f5a6ee17d1f0940
5
5
  SHA512:
6
- metadata.gz: acfd00b12f982fcf9f49fd794a94fd8be728e3c72a0e45495823c91527f44e1dfe996df3e70afe7d0221dff632222fb3ea17d14492f2dceaa4d2e548f2060675
7
- data.tar.gz: 722d0eb8f1f40347bab42953104c8f58cc090b3c464ff25b07ea239d766c0871376c3bb3a45417251d982cec997f688e44e67b9ee002c15b0c91c054e46b9664
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 = "myapp.com/webhook")
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
- # "<?xml version=\"1.0\" ?> <QBXML> <QBXMLMsgsRs> ... </QBXMLMsgsRs> </QBXML>",
76
- # "webhook_url"=>"myapp.com/webhook",
77
- # "request_xml"=>
78
- # "<?xml version=\"1.0\"?><?qbxml version=\"16.0\"?><QBXML> ... </QBXMLMsgsRq></QBXML>"}}
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module QubeSync
4
- VERSION = "0.1.3"
4
+ VERSION = "0.2.1"
5
5
  end
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(',') => [ts, *signatures]
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) => { timestamp:, signatures:}
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.3
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: 2025-02-19 00:00:00.000000000 Z
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.5.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: []