@callforge/tracking-client 0.6.0 → 0.6.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.
Files changed (2) hide show
  1. package/README.md +66 -98
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,8 +1,6 @@
1
1
  # @callforge/tracking-client
2
2
 
3
- Lightweight client library for the CallForge tracking API. Handles location-aware phone number assignment with aggressive caching and preload optimization.
4
-
5
- **v0.6.0** - Adds `createCallIntent()` helper for click/callback deterministic attribution and fixes ESM/CJS exports.
3
+ Lightweight client library for the CallForge tracking API. Handles location-aware phone number assignment with aggressive caching and optional preload optimization.
6
4
 
7
5
  ## Installation
8
6
 
@@ -26,12 +24,13 @@ const snippet = getPreloadSnippet({ categoryId: 'your-category-id' });
26
24
  ```
27
25
 
28
26
  Generated HTML:
27
+
29
28
  ```html
30
29
  <link rel="preconnect" href="https://tracking.callforge.io">
31
30
  <script>/* preload script */</script>
32
31
  ```
33
32
 
34
- ### 2. Initialize and use the client
33
+ ### 2. Initialize and fetch a tracking session
35
34
 
36
35
  ```typescript
37
36
  import { CallForge } from '@callforge/tracking-client';
@@ -41,40 +40,52 @@ const client = CallForge.init({
41
40
  // endpoint: 'https://tracking-dev.callforge.io', // Optional: override for dev
42
41
  });
43
42
 
44
- // Promise style
45
43
  const session = await client.getSession();
46
44
  console.log(session.phoneNumber); // "+17705550000" or null
47
45
  console.log(session.location); // { city: "Woodstock", state: "Georgia", stateCode: "GA" } or null
46
+ ```
48
47
 
49
- // Subscription style
50
- client.onReady((session) => {
51
- document.getElementById('phone').textContent = session.phoneNumber;
52
- document.getElementById('city').textContent = session.location?.city;
48
+ ### 3. Deterministic click/callback attribution (optional)
49
+
50
+ If you initiate calls programmatically (click-to-call / callback), you can request a short-lived `callIntentToken`. CallForge will consume this once to deterministically map the call back to the web session that requested it.
51
+
52
+ ```typescript
53
+ // In the browser:
54
+ const { callIntentToken } = await client.createCallIntent();
55
+
56
+ // Send to your backend and attach to the call you initiate
57
+ await fetch('/api/callback', {
58
+ method: 'POST',
59
+ headers: { 'Content-Type': 'application/json' },
60
+ body: JSON.stringify({ callIntentToken }),
53
61
  });
54
62
  ```
55
63
 
56
- ### 3. GA4 Integration
64
+ Notes:
65
+ - `callIntentToken` is short-lived and single-use.
66
+ - Treat it as an opaque secret (do not log it).
67
+
68
+ ### 4. GA4 Integration
57
69
 
58
70
  To enable GA4 call event tracking, provide your GA4 Measurement ID:
59
71
 
60
72
  ```typescript
61
73
  const client = CallForge.init({
62
74
  categoryId: 'your-category-id',
63
- ga4MeasurementId: 'G-XXXXXXXXXX', // Required for GA4 integration
75
+ ga4MeasurementId: 'G-XXXXXXXXXX',
64
76
  });
65
77
  ```
66
78
 
67
- **Requirements:**
68
- 1. Google Analytics 4 must be installed on your site (`gtag.js`)
69
- 2. Provide `ga4MeasurementId` in client config
70
- 3. Configure GA4 credentials in CallForge dashboard (Categories → Edit → GA4 tab)
79
+ Requirements:
80
+ 1. Google Analytics 4 must be installed on your site (`gtag.js`).
81
+ 2. Provide `ga4MeasurementId` in client config.
82
+ 3. Configure GA4 credentials in CallForge dashboard.
71
83
 
72
- **How it works:**
73
- - Uses `gtag('get', measurementId, 'client_id', callback)` to capture the GA4 client ID
74
- - Callback fires when GA4 is ready - no polling needed
75
- - Client ID is automatically sent to CallForge for call event attribution
84
+ How it works:
85
+ - Uses `gtag('get', measurementId, 'client_id', callback)` to capture the GA4 client ID.
86
+ - Client ID is sent to CallForge for call event attribution.
76
87
 
77
- **Manual override:** If you need to pass a custom GA4 client ID:
88
+ Manual override:
78
89
 
79
90
  ```typescript
80
91
  client.setParams({
@@ -82,7 +93,7 @@ client.setParams({
82
93
  });
83
94
  ```
84
95
 
85
- ### 4. Track conversion parameters (optional)
96
+ ### 5. Track conversion parameters (optional)
86
97
 
87
98
  The client automatically captures ad platform click IDs from the URL:
88
99
 
@@ -95,14 +106,13 @@ The client automatically captures ad platform click IDs from the URL:
95
106
  You can also add custom parameters:
96
107
 
97
108
  ```typescript
98
- // Add custom tracking parameters
99
109
  client.setParams({
100
110
  customerId: '456',
101
111
  landingPage: 'pricing',
102
112
  });
103
113
 
104
114
  // Parameters are automatically sent with every API request
105
- const session = await client.getSession();
115
+ await client.getSession();
106
116
  ```
107
117
 
108
118
  ## API Reference
@@ -115,18 +125,19 @@ Initialize the tracking client.
115
125
  interface CallForgeConfig {
116
126
  categoryId: string; // Required - which number pool to use
117
127
  endpoint?: string; // Optional - defaults to 'https://tracking.callforge.io'
118
- ga4MeasurementId?: string; // Optional - GA4 Measurement ID (e.g., "G-XXXXXXXXXX")
119
- // Enables gtag callback instead of cookie polling
128
+ siteKey?: string; // Optional - cache partition key (defaults to window.location.hostname)
129
+ ga4MeasurementId?: string; // Optional - GA4 Measurement ID (e.g., 'G-XXXXXXXXXX')
120
130
  }
121
131
  ```
122
132
 
123
133
  ### `client.getSession()`
124
134
 
125
- Get tracking session data. Returns cached data if valid, otherwise fetches from API.
135
+ Get tracking session data. Returns cached data if valid, otherwise fetches from the API.
126
136
 
127
137
  ```typescript
128
138
  interface TrackingSession {
129
- sessionId: string | null;
139
+ sessionToken: string; // Signed, opaque token used to refresh the session
140
+ leaseId: string | null; // Deterministic assignment lease ID (when available)
130
141
  phoneNumber: string | null;
131
142
  location: {
132
143
  city: string;
@@ -136,11 +147,20 @@ interface TrackingSession {
136
147
  }
137
148
  ```
138
149
 
139
- **Behavior:**
140
- - Returns `null` values immediately if no `loc_physical_ms` in URL (no API call)
141
- - Returns cached data if valid (same location, not expired)
142
- - Fetches fresh data if cache expired or location changed
143
- - Throws on network errors or API errors
150
+ Behavior:
151
+ - Returns cached data if valid.
152
+ - Fetches fresh data when cache is missing/expired.
153
+ - If `loc_physical_ms` is present in the URL, cached sessions are only reused when it matches the cached `locId`.
154
+ - Throws on network errors or API errors.
155
+
156
+ ### `client.createCallIntent()`
157
+
158
+ Create a short-lived call intent token for click/callback deterministic attribution.
159
+
160
+ ```typescript
161
+ const intent = await client.createCallIntent();
162
+ console.log(intent.callIntentToken);
163
+ ```
144
164
 
145
165
  ### `client.onReady(callback)`
146
166
 
@@ -164,11 +184,10 @@ client.setParams({
164
184
  });
165
185
  ```
166
186
 
167
- **Behavior:**
168
- - Merges with existing params (later calls override earlier values)
169
- - Parameters are sent with every `getSession()` API request
170
- - Persisted in localStorage alongside session data
171
- - Auto-captured params (gclid, etc.) are included automatically
187
+ Behavior:
188
+ - Merges with existing params (later calls override earlier values).
189
+ - Parameters are sent with every `getSession()` API request.
190
+ - Persisted in localStorage alongside session data.
172
191
 
173
192
  ### `getPreloadSnippet(config)`
174
193
 
@@ -180,6 +199,7 @@ import { getPreloadSnippet } from '@callforge/tracking-client';
180
199
  const html = getPreloadSnippet({
181
200
  categoryId: 'your-category-id',
182
201
  endpoint: 'https://tracking.callforge.io', // Optional
202
+ siteKey: 'example.com', // Optional
183
203
  });
184
204
  ```
185
205
 
@@ -194,32 +214,22 @@ The client automatically extracts these parameters from the URL:
194
214
  | `gclid` | Google Ads Click ID |
195
215
  | `gbraid` | Google app-to-web (iOS 14+) |
196
216
  | `wbraid` | Google web-to-app |
197
- | `msclkid` | Microsoft/Bing Ads |
198
- | `fbclid` | Facebook/Meta Ads |
199
-
200
- **Note:** `ga4ClientId` is captured via `gtag('get')` callback when `ga4MeasurementId` is configured.
201
-
202
- ### Persistence
203
-
204
- - Parameters are stored in localStorage alongside the session
205
- - On subsequent visits, cached params are used (URL may no longer have them)
206
- - Custom params via `setParams()` merge with auto-captured params
207
- - Later values override earlier ones (custom > cached > auto-captured)
217
+ | `msclkid` | Microsoft/Bing Ads Click ID |
218
+ | `fbclid` | Facebook/Meta Ads Click ID |
208
219
 
209
220
  ### API Request Format
210
221
 
211
- Parameters are sent as sorted query string for cache consistency:
222
+ Parameters are sent as a sorted query string for cache consistency:
212
223
 
213
224
  ```
214
- /v1/tracking/session?categoryId=cat-123&fbclid=456&gclid=abc&loc_physical_ms=1014221
225
+ /v1/tracking/session?categoryId=cat-123&fbclid=456&gclid=abc&loc_physical_ms=1014221&sessionToken=...
215
226
  ```
216
227
 
217
228
  ## Caching Behavior
218
229
 
219
- - **Cache key:** `loc_physical_ms` parameter from URL
220
- - **TTL:** 30 minutes (controlled by server)
221
- - **Storage:** localStorage (falls back to memory if unavailable)
222
- - **Invalidation:** Cache clears when location changes
230
+ - Cache key: `cf_tracking_v1_<siteKey>_<categoryId>`
231
+ - TTL: controlled by the server `expiresAt` response (currently 30 minutes)
232
+ - Storage: localStorage (falls back to memory if unavailable)
223
233
 
224
234
  ## Error Handling
225
235
 
@@ -229,7 +239,7 @@ try {
229
239
  if (session.phoneNumber) {
230
240
  // Use phone number
231
241
  } else {
232
- // No phone number available for this location
242
+ // No phone number available
233
243
  }
234
244
  } catch (err) {
235
245
  // Network error or API error
@@ -248,52 +258,10 @@ import type {
248
258
  TrackingLocation,
249
259
  TrackingParams,
250
260
  ReadyCallback,
261
+ CallIntentResponse,
251
262
  } from '@callforge/tracking-client';
252
263
  ```
253
264
 
254
- ### TrackingParams
255
-
256
- ```typescript
257
- interface TrackingParams {
258
- gclid?: string; // Google Ads Click ID
259
- gbraid?: string; // Google app-to-web (iOS 14+)
260
- wbraid?: string; // Google web-to-app
261
- msclkid?: string; // Microsoft/Bing Ads
262
- fbclid?: string; // Facebook/Meta Ads
263
- ga4ClientId?: string; // Google Analytics 4 Client ID (auto-captured via gtag callback)
264
- [key: string]: string | undefined; // Custom params
265
- }
266
- ```
267
-
268
- ## GA4 Events
269
-
270
- When GA4 is configured for a category, CallForge sends these events to Google Analytics 4 via the Measurement Protocol:
271
-
272
- | Event Name | When Sent | Description |
273
- |------------|-----------|-------------|
274
- | `phone_call` | Call initiated | A phone call was placed to the tracking number |
275
- | `call_conversion` | Call qualified | The call met conversion criteria (e.g., duration threshold) |
276
- | `call_conversion_billable` | Call billable | The call was both qualified AND billable |
277
-
278
- **Event Parameters:**
279
-
280
- All events include:
281
- - `session_id` - CallForge session ID
282
- - `phone_number` - Tracking number dialed
283
- - `category` - Category slug
284
-
285
- `call_conversion` and `call_conversion_billable` also include:
286
- - `call_duration` - Call duration in seconds
287
- - `buyer` - Buyer the call was routed to (if applicable)
288
-
289
- **Setup:**
290
- 1. In Google Analytics 4, go to Admin → Data Streams → your web stream
291
- 2. Copy the **Measurement ID** (e.g., `G-XXXXXXXXXX`)
292
- 3. Go to Admin → Data Streams → Measurement Protocol API secrets → Create
293
- 4. Copy the **API Secret**
294
- 5. In CallForge dashboard: Categories → Edit category → GA4 tab
295
- 6. Enable GA4, paste Measurement ID and API Secret, save
296
-
297
265
  ## Environment URLs
298
266
 
299
267
  | Environment | Endpoint |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@callforge/tracking-client",
3
- "version": "0.6.0",
3
+ "version": "0.6.1",
4
4
  "main": "dist/index.js",
5
5
  "module": "dist/index.mjs",
6
6
  "types": "dist/index.d.ts",