tango-api-client 0.1.2 → 0.2.0
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/CHANGELOG.md +6 -0
- data/README.md +14 -0
- data/lib/tango/api/client/version.rb +1 -1
- data/lib/tango/api/client.rb +5 -0
- data/lib/tango/api/resources/base.rb +13 -0
- data/lib/tango/api/resources/webhooks.rb +71 -0
- 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: f7475c292cfcb29d85404d80d86cb94f47c4d0497dcfd97743366be0af176933
|
|
4
|
+
data.tar.gz: 69d61b9a8d860fd5734557d61aec61ae8d969634803c3a97e87f23db9ead35e1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1243790a92ce6dba4870e506fb86e00a9436bf7c9c6e206e6d7d908b7011a0a06139ee0ba2decd3f6d0b4dd1341bd856484b66c7ad252886b88f091cb0faebc3
|
|
7
|
+
data.tar.gz: 6205cc363c7e1d2ef985b31fedb377a53c242d9d7339568d1bb5480be0aa8aecfc249fb1b71dc3b05efc4d208ef8e65311c405cb40244f31b0029404fa2262be
|
data/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
- Nothing yet.
|
|
7
7
|
|
|
8
|
+
## [0.2.0] - 2026-11-09
|
|
9
|
+
- Add Webhooks resource for subscription management: `create`, `list`, `get`, `update`, `delete`, `renew`
|
|
10
|
+
- Add webhook event history and redelivery: `events` (cursor paging, revision range) and `replay` (`fromRevision`/`toRevision` query params)
|
|
11
|
+
- Add `test` to trigger Tango's test deliveries (`ConnectivityTest`, or an event type such as `ItemAvailability` in the sandbox)
|
|
12
|
+
- `Resources::Base#post_without_body` for POST action endpoints that take only path and query parameters
|
|
13
|
+
|
|
8
14
|
## [0.1.2] - 2025-11-12
|
|
9
15
|
- Add Brand Categories resource: `get` method for `/brandCategories` endpoint
|
|
10
16
|
|
data/README.md
CHANGED
|
@@ -115,6 +115,19 @@ client.orders.create(
|
|
|
115
115
|
|
|
116
116
|
# Resend with Idempotency-Key (prevents duplicate resends)
|
|
117
117
|
client.orders.resend('ORDER-123', idempotency_key: idempotency)
|
|
118
|
+
|
|
119
|
+
# Webhook subscriptions (HMAC-signed ItemAvailability events)
|
|
120
|
+
sub = client.webhooks.create(
|
|
121
|
+
url: 'https://example.com/v1/tango/webhooks',
|
|
122
|
+
eventTypes: ['ItemAvailability'],
|
|
123
|
+
headers: [{ name: 'X-Subscription-Generation', value: '1' }],
|
|
124
|
+
payloadVerificationMethod: 'HMAC',
|
|
125
|
+
hmacSharedSecretKey: Base64.strict_encode64(SecureRandom.bytes(32))
|
|
126
|
+
)
|
|
127
|
+
client.webhooks.renew(sub['webhookId']) # => { 'webhookId', 'expiresAt' }
|
|
128
|
+
client.webhooks.events(sub['webhookId'], fromRevision: 0, maxResults: 100)
|
|
129
|
+
client.webhooks.replay(sub['webhookId'], from_revision: 0) # redeliver up to 3 months back
|
|
130
|
+
client.webhooks.test(sub['webhookId'], 'ItemAvailability') # sandbox only
|
|
118
131
|
```
|
|
119
132
|
|
|
120
133
|
### Resources overview
|
|
@@ -130,6 +143,7 @@ client.orders.resend('ORDER-123', idempotency_key: idempotency)
|
|
|
130
143
|
| Status | `Tango::Api::Resources::Status` | `get` | GET `/status` |
|
|
131
144
|
| Exchange Rates | `Tango::Api::Resources::ExchangeRates` | `get(params = {})`, `get_for_utid(utid, params = {})` | GET `/exchangeRates`; GET `/exchangeRates/{utid}` |
|
|
132
145
|
| Choice Products | `Tango::Api::Resources::ChoiceProducts` | `get(params = {})`, `get_for_utid(utid)`, `catalog(choice_product_utid, params = {})` | GET `/choiceProducts`; GET `/choiceProducts/{utid}`; GET `/choiceProducts/{utid}/catalog` |
|
|
146
|
+
| Webhooks | `Tango::Api::Resources::Webhooks` | `create(body)`, `list(params = {})`, `get(webhook_id)`, `update(webhook_id, body)`, `delete(webhook_id)`, `renew(webhook_id)`, `events(webhook_id, params = {})`, `replay(webhook_id, from_revision:, to_revision: nil)`, `test(webhook_id, test_name)` | POST/GET `/webhooks`; GET/PATCH/DELETE `/webhooks/{webhookId}`; POST `/webhooks/{webhookId}/renew`; GET `/webhooks/{webhookId}/events`; POST `/webhooks/{webhookId}/replay`; POST `/webhooks/{webhookId}/tests/{testName}` |
|
|
133
147
|
|
|
134
148
|
### Smoke test
|
|
135
149
|
|
data/lib/tango/api/client.rb
CHANGED
|
@@ -20,6 +20,7 @@ require_relative "resources/status"
|
|
|
20
20
|
require_relative "resources/exchange_rates"
|
|
21
21
|
require_relative "resources/choice_products"
|
|
22
22
|
require_relative "resources/brand_categories"
|
|
23
|
+
require_relative "resources/webhooks"
|
|
23
24
|
|
|
24
25
|
module Tango
|
|
25
26
|
module Api
|
|
@@ -83,6 +84,10 @@ module Tango
|
|
|
83
84
|
Resources::BrandCategories.new(@conn)
|
|
84
85
|
end
|
|
85
86
|
|
|
87
|
+
def webhooks
|
|
88
|
+
Resources::Webhooks.new(@conn)
|
|
89
|
+
end
|
|
90
|
+
|
|
86
91
|
private
|
|
87
92
|
|
|
88
93
|
def build_connection
|
|
@@ -53,6 +53,19 @@ module Tango
|
|
|
53
53
|
raise map_faraday_error(e)
|
|
54
54
|
end
|
|
55
55
|
|
|
56
|
+
# POST with no request body, for action endpoints that take only path and query
|
|
57
|
+
# parameters (e.g. webhook renew, replay, tests). Empty or non-JSON success bodies
|
|
58
|
+
# such as "OK" are returned as {} or { "raw" => body }.
|
|
59
|
+
def post_without_body(path, params = nil)
|
|
60
|
+
response = @conn.post(path) { |req| req.params.update(params) if params }
|
|
61
|
+
ensure_success_or_raise(response)
|
|
62
|
+
return {} if response.body.to_s.strip.empty?
|
|
63
|
+
|
|
64
|
+
parse_json_response(response)
|
|
65
|
+
rescue Faraday::Error => e
|
|
66
|
+
raise map_faraday_error(e)
|
|
67
|
+
end
|
|
68
|
+
|
|
56
69
|
def delete_json(path)
|
|
57
70
|
response = @conn.delete(path)
|
|
58
71
|
ensure_success_or_raise(response)
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Tango
|
|
4
|
+
module Api
|
|
5
|
+
module Resources
|
|
6
|
+
# Webhook subscriptions: create, manage, renew, and read or redeliver past events.
|
|
7
|
+
class Webhooks < Base
|
|
8
|
+
# POST /webhooks
|
|
9
|
+
# Body keys: url (required), eventTypes and/or categories, headers ([{ name:, value: }]),
|
|
10
|
+
# payloadVerificationMethod ("HMAC", "X509" or "NONE"), hmacSharedSecretKey (base64),
|
|
11
|
+
# signingCertificate (base64).
|
|
12
|
+
# Returns { "webhookId" => ..., "expiresAt" => ... }.
|
|
13
|
+
def create(body)
|
|
14
|
+
post_json("webhooks", body)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# GET /webhooks
|
|
18
|
+
# Params may include: prevCursor, nextCursor, maxResults (default 10, max 200), url,
|
|
19
|
+
# headerName, headerValue, categories, eventTypes, expiresAtFrom/To, createdAtFrom/To.
|
|
20
|
+
def list(params = {})
|
|
21
|
+
get_json("webhooks", params)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# GET /webhooks/{webhookId}
|
|
25
|
+
def get(webhook_id)
|
|
26
|
+
get_json("webhooks/#{webhook_id}")
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# PATCH /webhooks/{webhookId}
|
|
30
|
+
# Body keys as for #create; all optional.
|
|
31
|
+
def update(webhook_id, body)
|
|
32
|
+
patch_json("webhooks/#{webhook_id}", body)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# DELETE /webhooks/{webhookId}
|
|
36
|
+
def delete(webhook_id)
|
|
37
|
+
delete_json("webhooks/#{webhook_id}")
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# POST /webhooks/{webhookId}/renew
|
|
41
|
+
# Returns { "webhookId" => ..., "expiresAt" => ... }.
|
|
42
|
+
def renew(webhook_id)
|
|
43
|
+
post_without_body("webhooks/#{webhook_id}/renew")
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# GET /webhooks/{webhookId}/events
|
|
47
|
+
# Params may include: fromRevision, toRevision, prevCursor, nextCursor, maxResults.
|
|
48
|
+
# Returns a page: { "items" => [...], "nextCursor", "nextPageAvailable", ... }.
|
|
49
|
+
def events(webhook_id, params = {})
|
|
50
|
+
get_json("webhooks/#{webhook_id}/events", params)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# POST /webhooks/{webhookId}/replay?fromRevision=&toRevision=
|
|
54
|
+
# Redelivers past events (up to three months old). Omitting to_revision replays
|
|
55
|
+
# through the latest event.
|
|
56
|
+
def replay(webhook_id, from_revision:, to_revision: nil)
|
|
57
|
+
params = { fromRevision: from_revision }
|
|
58
|
+
params[:toRevision] = to_revision unless to_revision.nil?
|
|
59
|
+
post_without_body("webhooks/#{webhook_id}/replay", params)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# POST /webhooks/{webhookId}/tests/{testName}
|
|
63
|
+
# testName: ConnectivityTest (any environment) or, in the sandbox only, an event type
|
|
64
|
+
# such as ItemAvailability.
|
|
65
|
+
def test(webhook_id, test_name)
|
|
66
|
+
post_without_body("webhooks/#{webhook_id}/tests/#{test_name}")
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: tango-api-client
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Puneeth Kumar DN
|
|
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: activesupport
|
|
@@ -96,6 +95,7 @@ files:
|
|
|
96
95
|
- lib/tango/api/resources/funds.rb
|
|
97
96
|
- lib/tango/api/resources/orders.rb
|
|
98
97
|
- lib/tango/api/resources/status.rb
|
|
98
|
+
- lib/tango/api/resources/webhooks.rb
|
|
99
99
|
- sig/tango/api/client.rbs
|
|
100
100
|
homepage: https://github.com/Engagedly-Inc/tango-api-client
|
|
101
101
|
licenses:
|
|
@@ -105,7 +105,6 @@ metadata:
|
|
|
105
105
|
source_code_uri: https://github.com/Engagedly-Inc/tango-api-client
|
|
106
106
|
changelog_uri: https://github.com/Engagedly-Inc/tango-api-client/blob/master/CHANGELOG.md
|
|
107
107
|
rubygems_mfa_required: 'true'
|
|
108
|
-
post_install_message:
|
|
109
108
|
rdoc_options: []
|
|
110
109
|
require_paths:
|
|
111
110
|
- lib
|
|
@@ -120,8 +119,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
120
119
|
- !ruby/object:Gem::Version
|
|
121
120
|
version: '0'
|
|
122
121
|
requirements: []
|
|
123
|
-
rubygems_version: 3.
|
|
124
|
-
signing_key:
|
|
122
|
+
rubygems_version: 3.6.9
|
|
125
123
|
specification_version: 4
|
|
126
124
|
summary: Ruby client for Tango (BHN) API with dual auth and robust errors.
|
|
127
125
|
test_files: []
|