shedcloud-partner_api 0.1.0 → 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/AGENTS.md +3 -2
- data/CHANGELOG.md +14 -1
- data/README.md +45 -5
- data/lib/shedcloud/partner_api/client.rb +2 -0
- data/lib/shedcloud/partner_api/resources/site_events.rb +62 -0
- data/lib/shedcloud/partner_api/scopes.rb +4 -0
- data/lib/shedcloud/partner_api/version.rb +1 -1
- data/lib/shedcloud/partner_api.rb +1 -0
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 734c3d0eea78c90ba7776d78e851458f70cdaea30bdfa5925825bdafe2297ad3
|
|
4
|
+
data.tar.gz: 48dae1fe95a8fbf76f9284fe4ef8f8079609ecb824358302f4dd78988a245805
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7fe825bcd1852876eb1f6519ce6d3ce935dcdeece6af55c241a0ed4f57bd9f19c04783f9d45caa4ec3dd6ab8087dc0689a707592378f086e3e9c1df5cf3a4eb1
|
|
7
|
+
data.tar.gz: 6513611c7663bfaa6d252340b5a68b8a0f2b8dbbd7df94b90928e599ce6007d58a946e4bc6c9b0f0e0bb977014f50ff22f00c6efaeb52e06ed3dff68cac6d54c
|
data/AGENTS.md
CHANGED
|
@@ -23,7 +23,7 @@ shedcloud-gem/
|
|
|
23
23
|
│ ├── errors.rb
|
|
24
24
|
│ ├── scopes.rb
|
|
25
25
|
│ ├── webhooks.rb
|
|
26
|
-
│ └── resources/ # one file per /partner/v1 resource
|
|
26
|
+
│ └── resources/ # one file per /partner/v1 resource (site_events.rb = snake_case POST body)
|
|
27
27
|
├── spec/
|
|
28
28
|
├── examples/
|
|
29
29
|
└── shedcloud-partner_api.gemspec
|
|
@@ -36,7 +36,8 @@ shedcloud-gem/
|
|
|
36
36
|
3. **Scopes** live in `scopes.rb` and must stay in sync with `shedcloud-api-go/internal/partnerauth/scopes.go`.
|
|
37
37
|
4. **Auth stays outside resource classes.** Resources only call `HttpClient#request`. Token exchange/caching belongs in `auth_provider.rb`.
|
|
38
38
|
5. **Keep the surface small.** No portal admin endpoints (`/v1/settings/api-keys`, etc.).
|
|
39
|
-
6.
|
|
39
|
+
6. **`site_events.track` sends its body in snake_case** — the ingest endpoint shares its envelope with the configurator tracker rather than the camelCase style of the rest of `/partner/v1`. Do not normalize keys.
|
|
40
|
+
7. After changing `lib/`, run `bundle exec rspec`.
|
|
40
41
|
|
|
41
42
|
## Adding a resource
|
|
42
43
|
|
data/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## 0.
|
|
3
|
+
## 0.2.0 — 2026-07-19
|
|
4
|
+
|
|
5
|
+
- **Site events** — `client.site_events.track`, `list`, and `each` for
|
|
6
|
+
`POST/GET /partner/v1/site-events` (visitor behavioral tracking from partner
|
|
7
|
+
marketing sites). New scopes `partner-api.site-events.read` and
|
|
8
|
+
`partner-api.site-events.write`. Ingest uses a **snake_case** wire body
|
|
9
|
+
(`session_id`, `events[].event_type`, …) — pass the hash through as-is; do
|
|
10
|
+
not camelCase-convert it. Reads use normal camelCase query params
|
|
11
|
+
(`sessionId`, `types`, `from`, `to`). Batch-only ingest (max 25 events per
|
|
12
|
+
call); server-side use only.
|
|
13
|
+
- Parity with `@shedcloud/partner-api` site-events resource and
|
|
14
|
+
`shedcloud-api-go` Partner API changelog entry (2026-07-19).
|
|
15
|
+
|
|
16
|
+
## 0.1.0 — 2026-07-13
|
|
4
17
|
|
|
5
18
|
- Initial `shedcloud-partner_api` Ruby gem
|
|
6
19
|
- Built-in hosts: production `https://go.shedcloud.com` (default), sandbox `https://api.shedcloudtest.com`
|
data/README.md
CHANGED
|
@@ -92,6 +92,7 @@ Each resource maps to a section of the [hosted reference](https://go.shedcloud.c
|
|
|
92
92
|
| `client.payments` | `GET /partner/v1/payments` (read-only) |
|
|
93
93
|
| `client.documents` | `GET /partner/v1/documents`, download |
|
|
94
94
|
| `client.events` | `GET /partner/v1/events`, each iterator, redeliver, deliveries |
|
|
95
|
+
| `client.site_events` | `POST/GET /partner/v1/site-events` (visitor behavioral tracking) |
|
|
95
96
|
| `client.configurator_sessions` | `POST /partner/v1/configurator-sessions` |
|
|
96
97
|
|
|
97
98
|
### Idempotency and optimistic concurrency
|
|
@@ -118,6 +119,29 @@ For boolean query params that must be sent even when `false`:
|
|
|
118
119
|
client.quotes.list(converted: ShedCloud::PartnerApi::QueryValue.new(false))
|
|
119
120
|
```
|
|
120
121
|
|
|
122
|
+
### Site events (marketing-site behavioral tracking)
|
|
123
|
+
|
|
124
|
+
Proxy batched events from your backend — never call this from the browser with a partner key. The **ingest body is snake_case** on the wire; query params on reads are camelCase.
|
|
125
|
+
|
|
126
|
+
```ruby
|
|
127
|
+
res = client.site_events.track(
|
|
128
|
+
{
|
|
129
|
+
session_id: SecureRandom.uuid,
|
|
130
|
+
visitor_id: visitor_id_from_local_storage,
|
|
131
|
+
site_host: 'lelandssheds.com',
|
|
132
|
+
events: [
|
|
133
|
+
{ event_type: 'page.view', page: '/sheds/lofted-barn' },
|
|
134
|
+
{ event_type: 'cta.click', page: '/sheds/lofted-barn', payload: { cta: 'design-your-own' } }
|
|
135
|
+
]
|
|
136
|
+
}
|
|
137
|
+
)
|
|
138
|
+
puts res['accepted']
|
|
139
|
+
|
|
140
|
+
client.site_events.each(types: 'page.view') do |event|
|
|
141
|
+
puts event['eventId'], event['eventType'], event['source']
|
|
142
|
+
end
|
|
143
|
+
```
|
|
144
|
+
|
|
121
145
|
## Webhooks
|
|
122
146
|
|
|
123
147
|
Verify webhook deliveries with the subscription secret against the **raw** request body:
|
|
@@ -147,8 +171,10 @@ end
|
|
|
147
171
|
## Scopes
|
|
148
172
|
|
|
149
173
|
```ruby
|
|
150
|
-
ShedCloud::PartnerApi::Scopes::LOT_STOCK_READ
|
|
151
|
-
ShedCloud::PartnerApi::Scopes::ORDERS_WRITE
|
|
174
|
+
ShedCloud::PartnerApi::Scopes::LOT_STOCK_READ # partner-api.lot-stock.read
|
|
175
|
+
ShedCloud::PartnerApi::Scopes::ORDERS_WRITE # partner-api.orders.write
|
|
176
|
+
ShedCloud::PartnerApi::Scopes::SITE_EVENTS_WRITE # partner-api.site-events.write
|
|
177
|
+
ShedCloud::PartnerApi::Scopes::SITE_EVENTS_READ # partner-api.site-events.read
|
|
152
178
|
```
|
|
153
179
|
|
|
154
180
|
## Development
|
|
@@ -158,6 +184,19 @@ bundle install
|
|
|
158
184
|
bundle exec rspec
|
|
159
185
|
```
|
|
160
186
|
|
|
187
|
+
## Release
|
|
188
|
+
|
|
189
|
+
1. Bump `lib/shedcloud/partner_api/version.rb` and add a `CHANGELOG.md` entry.
|
|
190
|
+
2. Commit on `main`, then tag and push — GitHub Actions publishes to RubyGems on tag push:
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
git tag v0.2.0
|
|
194
|
+
git push origin main
|
|
195
|
+
git push origin v0.2.0
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
The workflow (`.github/workflows/release.yml`) runs `bundle exec rspec`, builds the gem, and pushes via `rubygems/release-gem` (OIDC). Tag format must be `v*` (e.g. `v0.2.0`).
|
|
199
|
+
|
|
161
200
|
## Versioning & changelog
|
|
162
201
|
|
|
163
202
|
The Partner API is **additive-only within `/partner/v1`**. This gem is tagged with semver in lockstep with API additions.
|
|
@@ -168,6 +207,7 @@ The Partner API is **additive-only within `/partner/v1`**. This gem is tagged wi
|
|
|
168
207
|
|
|
169
208
|
- Partner API reference: https://go.shedcloud.com/partner/reference
|
|
170
209
|
- Backend source of truth: `shedcloud-api-go/docs/PARTNER_API.md`
|
|
171
|
-
- TypeScript
|
|
172
|
-
- Go
|
|
173
|
-
-
|
|
210
|
+
- TypeScript/JavaScript: [`@shedcloud/partner-api`](https://github.com/Corland-Partners-LLC/shedcloud-npm)
|
|
211
|
+
- Go: [`shedcloud-gomod/partnerapi`](https://github.com/Corland-Partners-LLC/shedcloud-gomod)
|
|
212
|
+
- Python: [`shedcloud-partner-api`](https://github.com/Corland-Partners-LLC/shedcloud-pypi)
|
|
213
|
+
- PHP: [`shedcloud/partner-api`](https://github.com/Corland-Partners-LLC/shedcloud-php)
|
|
@@ -19,6 +19,7 @@ module ShedCloud
|
|
|
19
19
|
:payments,
|
|
20
20
|
:documents,
|
|
21
21
|
:events,
|
|
22
|
+
:site_events,
|
|
22
23
|
:configurator_sessions
|
|
23
24
|
|
|
24
25
|
def initialize(auth:, environment: nil, base_url: nil, transport: HttpTransport.new, timeout_seconds: 30.0,
|
|
@@ -57,6 +58,7 @@ module ShedCloud
|
|
|
57
58
|
@payments = Resources::Payments.new(@http)
|
|
58
59
|
@documents = Resources::Documents.new(@http)
|
|
59
60
|
@events = Resources::Events.new(@http)
|
|
61
|
+
@site_events = Resources::SiteEvents.new(@http)
|
|
60
62
|
@configurator_sessions = Resources::ConfiguratorSessions.new(@http)
|
|
61
63
|
end
|
|
62
64
|
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ShedCloud
|
|
4
|
+
module PartnerApi
|
|
5
|
+
module Resources
|
|
6
|
+
# Visitor behavioral events from partner marketing sites.
|
|
7
|
+
#
|
|
8
|
+
# Partner keys are server-side secrets: proxy events through your backend and
|
|
9
|
+
# never call these endpoints from the browser. Ingest is rate limited per
|
|
10
|
+
# company, so batch events client-side (max 25 per request). Always send a
|
|
11
|
+
# stable visitor_id — it stitches journeys across the marketing site and the
|
|
12
|
+
# 3D configurator. Raw events are retained ~90 days on reads.
|
|
13
|
+
class SiteEvents < Base
|
|
14
|
+
# POST /partner/v1/site-events (scope partner-api.site-events.write).
|
|
15
|
+
# Unlike most Partner API endpoints, the ingest body natively speaks
|
|
16
|
+
# snake_case on the wire (session_id, visitor_id, events[].event_type, ...).
|
|
17
|
+
def track(body, options: nil)
|
|
18
|
+
@http.request('POST', '/partner/v1/site-events', body: body, headers: option_headers(options)) || {}
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# GET /partner/v1/site-events (scope partner-api.site-events.read).
|
|
22
|
+
# Query params are camelCase on the wire: cursor, limit (max 200),
|
|
23
|
+
# sessionId, types, from, to.
|
|
24
|
+
def list(params = {})
|
|
25
|
+
query = params.dup
|
|
26
|
+
query[:types] = query[:types].join(',') if query[:types].is_a?(Array)
|
|
27
|
+
@http.request('GET', '/partner/v1/site-events', query: query) || {}
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def each(params = {})
|
|
31
|
+
cursor = params[:cursor].to_s
|
|
32
|
+
last_seen = cursor
|
|
33
|
+
|
|
34
|
+
loop do
|
|
35
|
+
page_params = params.dup
|
|
36
|
+
if cursor.empty?
|
|
37
|
+
page_params.delete(:cursor)
|
|
38
|
+
else
|
|
39
|
+
page_params[:cursor] = cursor
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
response = list(page_params)
|
|
43
|
+
data = response['data'].is_a?(Array) ? response['data'] : []
|
|
44
|
+
|
|
45
|
+
data.each do |event|
|
|
46
|
+
result = yield(event)
|
|
47
|
+
return last_seen if result == false
|
|
48
|
+
|
|
49
|
+
last_seen = event['eventId'] if event['eventId'].is_a?(String) && !event['eventId'].empty?
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
break unless response['hasMore'] && response['nextCursor'].is_a?(String) && !response['nextCursor'].empty?
|
|
53
|
+
|
|
54
|
+
cursor = response['nextCursor']
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
last_seen
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
@@ -24,6 +24,8 @@ module ShedCloud
|
|
|
24
24
|
PAYMENTS_WRITE = 'partner-api.payments.write'
|
|
25
25
|
DOCUMENTS_READ = 'partner-api.documents.read'
|
|
26
26
|
EVENTS_READ = 'partner-api.events.read'
|
|
27
|
+
SITE_EVENTS_READ = 'partner-api.site-events.read'
|
|
28
|
+
SITE_EVENTS_WRITE = 'partner-api.site-events.write'
|
|
27
29
|
CONFIGURATOR_SESSIONS_WRITE = 'partner-api.configurator-sessions.write'
|
|
28
30
|
DOMAINS_READ = 'partner-api.domains.read'
|
|
29
31
|
AGREEMENTS_READ = 'partner-api.agreements.read'
|
|
@@ -51,6 +53,8 @@ module ShedCloud
|
|
|
51
53
|
PAYMENTS_WRITE,
|
|
52
54
|
DOCUMENTS_READ,
|
|
53
55
|
EVENTS_READ,
|
|
56
|
+
SITE_EVENTS_READ,
|
|
57
|
+
SITE_EVENTS_WRITE,
|
|
54
58
|
CONFIGURATOR_SESSIONS_WRITE,
|
|
55
59
|
DOMAINS_READ,
|
|
56
60
|
AGREEMENTS_READ,
|
|
@@ -26,6 +26,7 @@ require_relative 'partner_api/resources/users'
|
|
|
26
26
|
require_relative 'partner_api/resources/payments'
|
|
27
27
|
require_relative 'partner_api/resources/documents'
|
|
28
28
|
require_relative 'partner_api/resources/events'
|
|
29
|
+
require_relative 'partner_api/resources/site_events'
|
|
29
30
|
require_relative 'partner_api/resources/configurator_sessions'
|
|
30
31
|
require_relative 'partner_api/client'
|
|
31
32
|
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: shedcloud-partner_api
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Corland Partners LLC
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-07-
|
|
11
|
+
date: 2026-07-19 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rake
|
|
@@ -77,6 +77,7 @@ files:
|
|
|
77
77
|
- lib/shedcloud/partner_api/resources/payments.rb
|
|
78
78
|
- lib/shedcloud/partner_api/resources/products.rb
|
|
79
79
|
- lib/shedcloud/partner_api/resources/quotes.rb
|
|
80
|
+
- lib/shedcloud/partner_api/resources/site_events.rb
|
|
80
81
|
- lib/shedcloud/partner_api/resources/stock_templates.rb
|
|
81
82
|
- lib/shedcloud/partner_api/resources/users.rb
|
|
82
83
|
- lib/shedcloud/partner_api/resources/work_orders.rb
|