cdp-edge 1.0.3 → 1.0.4

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.
@@ -140,7 +140,8 @@ const _wbraid = _urlParams.get('wbraid') || ''; // Google Ads (iOS, web-to-app,
140
140
  const _gbraid = _urlParams.get('gbraid') || ''; // Google Ads (app campaigns, privacy preserving)
141
141
 
142
142
  // TikTok
143
- const _ttclid = _urlParams.get('ttclid') || ''; // TikTok Ads click ID → complementa cookie _ttp
143
+ const _ttclid = _urlParams.get('ttclid') || ''; // TikTok Ads click ID → complementa cookie _ttp
144
+ const _msclkid = _urlParams.get('msclkid') || ''; // Microsoft Ads click ID
144
145
 
145
146
  // UTMs — rastreamento interno de origem de tráfego (independente da atribuição das plataformas)
146
147
  const _utms = {
@@ -217,7 +218,8 @@ const _getClickIDs = () => {
217
218
  wbraid: _wbraid || undefined,
218
219
  ttclid: _ttclid || undefined,
219
220
  ttp: document.cookie.match(/_ttp=([^;]+)/)?.[1] || undefined, // TikTok Pixel cookie — EMQ TikTok
220
- rclid: _urlParams.get('rclid') || undefined,
221
+ rclid: _urlParams.get('rclid') || undefined,
222
+ msclkid: _msclkid || undefined,
221
223
  };
222
224
  };
223
225
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cdp-edge",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
4
4
  "description": "CDP Edge - Quantum Tracking - Sistema multi-agente para tracking digital Cloudflare Native (Workers + D1)",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -389,7 +389,8 @@ export default {
389
389
  if (!trackPayload.wbraid && c.wbraid) trackPayload.wbraid = c.wbraid;
390
390
  if (!trackPayload.gbraid && c.gbraid) trackPayload.gbraid = c.gbraid;
391
391
  if (!trackPayload.ttclid && c.ttclid) trackPayload.ttclid = c.ttclid;
392
- if (!trackPayload.ttp && c.ttp) trackPayload.ttp = c.ttp;
392
+ if (!trackPayload.ttp && c.ttp) trackPayload.ttp = c.ttp;
393
+ if (!trackPayload.msclkid && c.msclkid) trackPayload.msclkid = c.msclkid;
393
394
  }
394
395
  if (payload.utms && typeof payload.utms === 'object') {
395
396
  const u = payload.utms as Record<string, string>;
@@ -761,15 +762,19 @@ export default {
761
762
  ctx.waitUntil(resolveDeviceGraph(env.DB, payload.userId, payload.email, payload.phone));
762
763
  }
763
764
 
764
- // Registrar em events deduplicação + label ML (INSERT OR IGNORE descarta duplicatas)
765
+ // Deduplicação server-side — INSERT OR IGNORE retorna changes=0 para duplicatas
765
766
  if (env.DB && payload.eventId) {
766
- ctx.waitUntil(
767
- env.DB.prepare(
767
+ try {
768
+ const dedup = await env.DB.prepare(
768
769
  `INSERT OR IGNORE INTO events (event_id, event_name, user_id, created_at)
769
770
  VALUES (?, ?, ?, datetime('now'))`
770
- ).bind(payload.eventId, eventName, payload.userId || null).run()
771
- .catch(() => { /* silencioso — não bloqueia o pipeline */ })
772
- );
771
+ ).bind(payload.eventId, eventName, payload.userId || null).run();
772
+ if (dedup.meta.changes === 0) {
773
+ return new Response(JSON.stringify({ ok: true, skipped: 'duplicate' }), { status: 200, headers });
774
+ }
775
+ } catch {
776
+ // Tabela ausente ou erro de DB — não bloqueia o pipeline
777
+ }
773
778
  }
774
779
 
775
780
  // R2 Audit Log — background
@@ -115,6 +115,7 @@ export async function upsertProfile(env: Env, eventName: string, payload: TrackP
115
115
  const {
116
116
  userId, email, phone,
117
117
  fbp, fbc, ttp, gclid, ttclid, gaClientId,
118
+ wbraid, gbraid, msclkid,
118
119
  city, state, country,
119
120
  engagementScore, userScore,
120
121
  } = payload;
@@ -131,8 +132,9 @@ export async function upsertProfile(env: Env, eventName: string, payload: TrackP
131
132
  await env.DB.prepare(`
132
133
  INSERT INTO user_profiles
133
134
  (user_id, email, phone, fbp, fbc, ttp, gclid, ttclid, ga_client_id,
135
+ wbraid, gbraid, msclkid,
134
136
  city, state, country, score, cohort_label, created_at, updated_at)
135
- VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,datetime('now'),datetime('now'))
137
+ VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,datetime('now'),datetime('now'))
136
138
  ON CONFLICT(user_id) DO UPDATE SET
137
139
  email = COALESCE(excluded.email, user_profiles.email),
138
140
  phone = COALESCE(excluded.phone, user_profiles.phone),
@@ -142,6 +144,9 @@ export async function upsertProfile(env: Env, eventName: string, payload: TrackP
142
144
  gclid = COALESCE(excluded.gclid, user_profiles.gclid),
143
145
  ttclid = COALESCE(excluded.ttclid, user_profiles.ttclid),
144
146
  ga_client_id = COALESCE(excluded.ga_client_id, user_profiles.ga_client_id),
147
+ wbraid = COALESCE(excluded.wbraid, user_profiles.wbraid),
148
+ gbraid = COALESCE(excluded.gbraid, user_profiles.gbraid),
149
+ msclkid = COALESCE(excluded.msclkid, user_profiles.msclkid),
145
150
  city = COALESCE(excluded.city, user_profiles.city),
146
151
  state = COALESCE(excluded.state, user_profiles.state),
147
152
  country = COALESCE(excluded.country, user_profiles.country),
@@ -158,6 +163,9 @@ export async function upsertProfile(env: Env, eventName: string, payload: TrackP
158
163
  gclid || null,
159
164
  ttclid || null,
160
165
  gaClientId || null,
166
+ wbraid || null,
167
+ gbraid || null,
168
+ msclkid || null,
161
169
  city || null,
162
170
  state || null,
163
171
  (country || (request as any).cf?.country || null),