cekat-event-sdk 0.1.0 → 0.3.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/README.md +16 -3
- data/lib/cekat_event_sdk/client.rb +4 -0
- data/lib/cekat_event_sdk/stripe.rb +36 -0
- data/lib/cekat_event_sdk/version.rb +1 -1
- data/lib/cekat_event_sdk.rb +2 -1
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7f9238be53f82b0d930ef3504555edaac544bf5743094a78cbcea5d8c470f4a6
|
|
4
|
+
data.tar.gz: 6f7f015e3391ad9782cfd0067208a5eda7250b19b030be4e5d67ef5b309cd124
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 457d2f820006ad24fb3fd5420765dd4b16d96d3970051cddcb278268d70c240290ceeba17e8b9dfa08d7df36adf2e63e4457f9e97a153f0469a130d5cb0b0e95
|
|
7
|
+
data.tar.gz: afd34ab171c2eec29a7e312360dee784108feeac0617e9c63628ced136b83914f6e063afd046201c80ecebe9cfc08035c32796998534d5430822a9020e27ed81
|
data/README.md
CHANGED
|
@@ -20,11 +20,12 @@ CEKAT = CekatEventSdk::Client.new(access_token: ENV.fetch("CEKAT_ACCESS_TOKEN"))
|
|
|
20
20
|
CEKAT.user_registration(email: "person@example.com", contact_name: "Person")
|
|
21
21
|
CEKAT.user_login(phone_number: "+628123456789")
|
|
22
22
|
CEKAT.order_created(email: "person@example.com", properties: { order_id: "o-1" })
|
|
23
|
+
CEKAT.form_submitted(email: "person@example.com", properties: { form_id: "contact" })
|
|
23
24
|
CEKAT.order_paid(email: "person@example.com", properties: { order_id: "o-1" }, amount: 125_000, currency: "IDR")
|
|
24
25
|
ack = CEKAT.custom_event("wishlist_updated", email: "person@example.com")
|
|
25
26
|
```
|
|
26
27
|
|
|
27
|
-
Every event method also accepts a `CekatEventSdk::EventInput` or a Hash instead of keyword attributes. `order_paid` additionally requires a finite `amount:` (Integer, Float, BigDecimal, or Rational) and a nonblank `currency:`, sent as the `amount` and `currency` properties; do not also put those keys in `properties`.
|
|
28
|
+
`form_submitted` sends the common `form_submitted` event (`is_common: true`). Every event method also accepts a `CekatEventSdk::EventInput` or a Hash instead of keyword attributes. `order_paid` additionally requires a finite `amount:` (Integer, Float, BigDecimal, or Rational) and a nonblank `currency:`, sent as the `amount` and `currency` properties; do not also put those keys in `properties`.
|
|
28
29
|
|
|
29
30
|
An `Acknowledgement` means Cekat accepted the event for **asynchronous processing**. It does not confirm durable storage, identity resolution, delivery completion, or analytics availability.
|
|
30
31
|
|
|
@@ -72,6 +73,18 @@ end
|
|
|
72
73
|
|
|
73
74
|
The visitor scope lives in fiber storage (`Fiber[]`), so it is isolated per request under threaded servers (Puma) and fiber-based servers (Falcon). Every scope restores the previous visitor when it ends, including when it raises, so long-running workers never leak a visitor ID between requests. Threads and fibers started inside a request begin with a copy of its scope. The scope ends when the middleware returns, so events emitted while a streaming response body is iterated must pass `visitor_id:` explicitly.
|
|
74
75
|
|
|
76
|
+
## Stripe metadata composition
|
|
77
|
+
|
|
78
|
+
Use the helper with the merchant's Stripe client; it does not create a Stripe request or send a Cekat event.
|
|
79
|
+
|
|
80
|
+
```ruby
|
|
81
|
+
metadata = CekatEventSdk::Stripe.merge_metadata(merchant_metadata, CekatEventSdk::Stripe.metadata_from_current_visitor["cekat_" + "visitor_id"])
|
|
82
|
+
# stripe.payment_intents.create(amount: 1200, currency: "usd", metadata: metadata)
|
|
83
|
+
# stripe.checkout.sessions.create(mode: "payment", metadata: metadata, payment_intent_data: { metadata: metadata })
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Only a trimmed 1–128 character `[A-Za-z0-9_-]` visitor becomes the Stripe visitor metadata entry. Merge returns a fresh hash, preserving merchant keys and leaving invalid or absent visitor input unchanged.
|
|
87
|
+
|
|
75
88
|
## Keep tracking off the request's critical path
|
|
76
89
|
|
|
77
90
|
Calls are synchronous, so each event adds its round-trip to the request. To send in the background, capture the visitor ID while the request scope is active and pass it explicitly:
|
|
@@ -119,7 +132,7 @@ Transport failures, timeouts, and HTTP 429, 500, 502, 503, and 504 are retried,
|
|
|
119
132
|
## Configuration
|
|
120
133
|
|
|
121
134
|
```ruby
|
|
122
|
-
CekatEventSdk::Client.new(access_token: token, base_url: "https://
|
|
135
|
+
CekatEventSdk::Client.new(access_token: token, base_url: "https://t.cekat.ai", timeout: 3, retry_count: 2)
|
|
123
136
|
```
|
|
124
137
|
|
|
125
138
|
`base_url` must be an absolute HTTP(S) origin without credentials, path, query, or fragment; the SDK always posts to `/api/events/ingest`. Requests send `User-Agent: cekat-event-sdk-ruby/<version>`.
|
|
@@ -132,7 +145,7 @@ The Net::HTTP transport opens a fresh connection per attempt, never follows redi
|
|
|
132
145
|
bundle install
|
|
133
146
|
bundle exec rake # core, Rack, and Rails specs plus RuboCop
|
|
134
147
|
RAILS_VERSION="~> 8.0.0" RACK_VERSION="~> 2.2" bundle update && bundle exec rake spec
|
|
135
|
-
./scripts/package --version 0.
|
|
148
|
+
./scripts/package --version 0.3.0 --output /absolute/empty-directory
|
|
136
149
|
```
|
|
137
150
|
|
|
138
151
|
`scripts/package` runs the specs, RuboCop, and `bundle-audit`, then builds the gem and a SHA-256 `manifest.json`. It never pushes, signs, or tags; releases to RubyGems run from the repository's `release-ruby.yml` workflow when a `ruby/vX.Y.Z` tag is pushed. `scripts/conformance` runs the shared conformance fixtures (see `conformance/README.md`); the three caller-cancellation cases are reported as `not_applicable` for Ruby.
|
|
@@ -48,6 +48,10 @@ module CekatEventSdk
|
|
|
48
48
|
track("order_created", true, event_from(event, attributes))
|
|
49
49
|
end
|
|
50
50
|
|
|
51
|
+
def form_submitted(event = nil, **attributes)
|
|
52
|
+
track("form_submitted", true, event_from(event, attributes))
|
|
53
|
+
end
|
|
54
|
+
|
|
51
55
|
# The required finite amount and nonblank currency are sent as the "amount" and "currency"
|
|
52
56
|
# properties; the event's properties must not already contain either key.
|
|
53
57
|
def order_paid(event = nil, amount:, currency:, **attributes)
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module CekatEventSdk
|
|
4
|
+
# Builds Stripe metadata for optional Cekat visitor correlation.
|
|
5
|
+
module Stripe
|
|
6
|
+
VISITOR_METADATA_KEY = "cekat_visitor_id"
|
|
7
|
+
|
|
8
|
+
module_function
|
|
9
|
+
|
|
10
|
+
def metadata_for_visitor(visitor_id)
|
|
11
|
+
normalized = valid_visitor_id(visitor_id)
|
|
12
|
+
normalized.nil? ? {} : { VISITOR_METADATA_KEY => normalized }
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def metadata_from_current_visitor
|
|
16
|
+
metadata_for_visitor(VisitorContext.current_visitor_id)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def merge_metadata(metadata, visitor_id)
|
|
20
|
+
merged = metadata.dup
|
|
21
|
+
normalized = valid_visitor_id(visitor_id)
|
|
22
|
+
merged[VISITOR_METADATA_KEY] = normalized unless normalized.nil?
|
|
23
|
+
merged
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def valid_visitor_id(visitor_id)
|
|
27
|
+
return nil unless visitor_id.is_a?(String)
|
|
28
|
+
|
|
29
|
+
normalized = visitor_id.strip
|
|
30
|
+
return nil unless normalized.match?(/\A[A-Za-z0-9_-]{1,128}\z/)
|
|
31
|
+
|
|
32
|
+
normalized
|
|
33
|
+
end
|
|
34
|
+
private_class_method :valid_visitor_id
|
|
35
|
+
end
|
|
36
|
+
end
|
data/lib/cekat_event_sdk.rb
CHANGED
|
@@ -4,7 +4,7 @@ require_relative "cekat_event_sdk/version"
|
|
|
4
4
|
|
|
5
5
|
# Cekat event SDK: submit identity-bearing events and correlate them with the browser visitor.
|
|
6
6
|
module CekatEventSdk
|
|
7
|
-
DEFAULT_BASE_URL = "https://
|
|
7
|
+
DEFAULT_BASE_URL = "https://t.cekat.ai"
|
|
8
8
|
INGEST_PATH = "/api/events/ingest"
|
|
9
9
|
VISITOR_HEADER = "X-Cekat-Visitor-ID"
|
|
10
10
|
VISITOR_COOKIE = "_cekat_visitor_id"
|
|
@@ -16,6 +16,7 @@ require_relative "cekat_event_sdk/event_input"
|
|
|
16
16
|
require_relative "cekat_event_sdk/acknowledgement"
|
|
17
17
|
require_relative "cekat_event_sdk/visitor_id_resolver"
|
|
18
18
|
require_relative "cekat_event_sdk/visitor_context"
|
|
19
|
+
require_relative "cekat_event_sdk/stripe"
|
|
19
20
|
require_relative "cekat_event_sdk/payload_builder"
|
|
20
21
|
require_relative "cekat_event_sdk/retry_policy"
|
|
21
22
|
require_relative "cekat_event_sdk/transport"
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: cekat-event-sdk
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Cekat
|
|
@@ -29,6 +29,7 @@ files:
|
|
|
29
29
|
- lib/cekat_event_sdk/rails.rb
|
|
30
30
|
- lib/cekat_event_sdk/response_decoder.rb
|
|
31
31
|
- lib/cekat_event_sdk/retry_policy.rb
|
|
32
|
+
- lib/cekat_event_sdk/stripe.rb
|
|
32
33
|
- lib/cekat_event_sdk/transport.rb
|
|
33
34
|
- lib/cekat_event_sdk/version.rb
|
|
34
35
|
- lib/cekat_event_sdk/visitor_context.rb
|