@sendmailos/sdk 1.0.0 → 1.1.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.
- package/dist/index.d.mts +88 -1
- package/dist/index.d.ts +88 -1
- package/dist/index.js +379 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +377 -1
- package/dist/index.mjs.map +1 -1
- package/dist/react/index.d.mts +159 -1
- package/dist/react/index.d.ts +159 -1
- package/dist/react/index.js +408 -0
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +407 -2
- package/dist/react/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -400,6 +400,93 @@ declare class SendMailOS {
|
|
|
400
400
|
static get version(): string;
|
|
401
401
|
}
|
|
402
402
|
|
|
403
|
+
interface PixelConfig {
|
|
404
|
+
/** Public API key (pk_live_... or pk_test_...) or legacy token */
|
|
405
|
+
token: string;
|
|
406
|
+
/** API endpoint for tracking events */
|
|
407
|
+
endpoint?: string;
|
|
408
|
+
/** Cookie name for anonymous ID storage */
|
|
409
|
+
cookieName?: string;
|
|
410
|
+
/** Enable debug logging */
|
|
411
|
+
debug?: boolean;
|
|
412
|
+
/** Respect Do Not Track browser setting (default: true) */
|
|
413
|
+
respectDNT?: boolean;
|
|
414
|
+
}
|
|
415
|
+
/** Alias for PixelConfig for SDK consistency */
|
|
416
|
+
type PixelOptions = PixelConfig;
|
|
417
|
+
interface TrackProps {
|
|
418
|
+
[key: string]: string | number | boolean | null | undefined | object;
|
|
419
|
+
}
|
|
420
|
+
/** Alias for TrackProps */
|
|
421
|
+
type TrackEventProperties = TrackProps;
|
|
422
|
+
/** Traits for identify calls */
|
|
423
|
+
interface IdentifyTraits {
|
|
424
|
+
first_name?: string;
|
|
425
|
+
last_name?: string;
|
|
426
|
+
[key: string]: string | number | boolean | null | undefined | object;
|
|
427
|
+
}
|
|
428
|
+
declare class SendmailPixel {
|
|
429
|
+
private config;
|
|
430
|
+
private anonymousId;
|
|
431
|
+
private initialized;
|
|
432
|
+
private rules;
|
|
433
|
+
private identifiedEmail;
|
|
434
|
+
constructor(config: PixelConfig);
|
|
435
|
+
init(): void;
|
|
436
|
+
/**
|
|
437
|
+
* Opt out of all tracking
|
|
438
|
+
*/
|
|
439
|
+
optOut(): void;
|
|
440
|
+
/**
|
|
441
|
+
* Opt back in to tracking
|
|
442
|
+
*/
|
|
443
|
+
optIn(): void;
|
|
444
|
+
/**
|
|
445
|
+
* Check if user has opted out
|
|
446
|
+
*/
|
|
447
|
+
isOptedOut(): boolean;
|
|
448
|
+
/**
|
|
449
|
+
* Reset identity (e.g., on logout)
|
|
450
|
+
*/
|
|
451
|
+
reset(): void;
|
|
452
|
+
/**
|
|
453
|
+
* Get current visitor/anonymous ID
|
|
454
|
+
*/
|
|
455
|
+
getVisitorId(): string;
|
|
456
|
+
/**
|
|
457
|
+
* Get identified email address
|
|
458
|
+
*/
|
|
459
|
+
getIdentifiedEmail(): string | null;
|
|
460
|
+
track(eventName: string, properties?: TrackProps): void;
|
|
461
|
+
identify(email: string, traits?: TrackProps): void;
|
|
462
|
+
pageView(): void;
|
|
463
|
+
private getOrSetAnonymousId;
|
|
464
|
+
private sendEvent;
|
|
465
|
+
loadRules(): Promise<void>;
|
|
466
|
+
/**
|
|
467
|
+
* Smart Auto-Detection of Page Type & Context
|
|
468
|
+
* Uses Dynamic Rules + Static Heuristics
|
|
469
|
+
*/
|
|
470
|
+
private detectContext;
|
|
471
|
+
private setupFormListeners;
|
|
472
|
+
private setupHistoryListeners;
|
|
473
|
+
private setCookie;
|
|
474
|
+
private getCookie;
|
|
475
|
+
private log;
|
|
476
|
+
private isDNTEnabled;
|
|
477
|
+
private checkUrlForSubscriber;
|
|
478
|
+
private setupDataAttributeTracking;
|
|
479
|
+
private getStoredEmail;
|
|
480
|
+
private storeEmail;
|
|
481
|
+
private isValidEmail;
|
|
482
|
+
}
|
|
483
|
+
/** Alias for SendmailPixel for SDK consistency */
|
|
484
|
+
declare const Pixel: typeof SendmailPixel;
|
|
485
|
+
/**
|
|
486
|
+
* Create pixel and attach global smp() function
|
|
487
|
+
*/
|
|
488
|
+
declare function createGlobalPixel(config: PixelConfig): SendmailPixel;
|
|
489
|
+
|
|
403
490
|
/**
|
|
404
491
|
* Custom error classes for SendMailOS SDK
|
|
405
492
|
*/
|
|
@@ -477,4 +564,4 @@ declare function constructWebhookEvent<T = unknown>(payload: string, headers: {
|
|
|
477
564
|
timestamp: string;
|
|
478
565
|
}, secret: string): T;
|
|
479
566
|
|
|
480
|
-
export { type ApiError, AuthenticationError, type CreateDomainRequest, type CreateDomainResponse, type CreateSubscriberRequest, type CreateSubscriberResponse, type CreateWebhookRequest, type DnsRecord, type Domain, type ListDomainsResponse, type ListSubscribersRequest, type ListSubscribersResponse, NotFoundError, RateLimitError, type SendCampaignRequest, type SendCampaignResponse, type SendEmailRequest, type SendEmailResponse, SendMailOS, SendMailOSError, type SendMailOSOptions, type Subscriber, ValidationError, type VerifyWebhookParams, type Webhook, type WebhookEvent, type WebhookEventType, constructWebhookEvent, SendMailOS as default, verifyWebhookSignature, verifyWebhookSignatureAsync };
|
|
567
|
+
export { type ApiError, AuthenticationError, type CreateDomainRequest, type CreateDomainResponse, type CreateSubscriberRequest, type CreateSubscriberResponse, type CreateWebhookRequest, type DnsRecord, type Domain, type IdentifyTraits, type ListDomainsResponse, type ListSubscribersRequest, type ListSubscribersResponse, NotFoundError, Pixel, type PixelConfig, type PixelOptions, RateLimitError, type SendCampaignRequest, type SendCampaignResponse, type SendEmailRequest, type SendEmailResponse, SendMailOS, SendMailOSError, type SendMailOSOptions, SendmailPixel, type Subscriber, type TrackEventProperties, type TrackProps, ValidationError, type VerifyWebhookParams, type Webhook, type WebhookEvent, type WebhookEventType, constructWebhookEvent, createGlobalPixel, SendMailOS as default, verifyWebhookSignature, verifyWebhookSignatureAsync };
|
package/dist/index.d.ts
CHANGED
|
@@ -400,6 +400,93 @@ declare class SendMailOS {
|
|
|
400
400
|
static get version(): string;
|
|
401
401
|
}
|
|
402
402
|
|
|
403
|
+
interface PixelConfig {
|
|
404
|
+
/** Public API key (pk_live_... or pk_test_...) or legacy token */
|
|
405
|
+
token: string;
|
|
406
|
+
/** API endpoint for tracking events */
|
|
407
|
+
endpoint?: string;
|
|
408
|
+
/** Cookie name for anonymous ID storage */
|
|
409
|
+
cookieName?: string;
|
|
410
|
+
/** Enable debug logging */
|
|
411
|
+
debug?: boolean;
|
|
412
|
+
/** Respect Do Not Track browser setting (default: true) */
|
|
413
|
+
respectDNT?: boolean;
|
|
414
|
+
}
|
|
415
|
+
/** Alias for PixelConfig for SDK consistency */
|
|
416
|
+
type PixelOptions = PixelConfig;
|
|
417
|
+
interface TrackProps {
|
|
418
|
+
[key: string]: string | number | boolean | null | undefined | object;
|
|
419
|
+
}
|
|
420
|
+
/** Alias for TrackProps */
|
|
421
|
+
type TrackEventProperties = TrackProps;
|
|
422
|
+
/** Traits for identify calls */
|
|
423
|
+
interface IdentifyTraits {
|
|
424
|
+
first_name?: string;
|
|
425
|
+
last_name?: string;
|
|
426
|
+
[key: string]: string | number | boolean | null | undefined | object;
|
|
427
|
+
}
|
|
428
|
+
declare class SendmailPixel {
|
|
429
|
+
private config;
|
|
430
|
+
private anonymousId;
|
|
431
|
+
private initialized;
|
|
432
|
+
private rules;
|
|
433
|
+
private identifiedEmail;
|
|
434
|
+
constructor(config: PixelConfig);
|
|
435
|
+
init(): void;
|
|
436
|
+
/**
|
|
437
|
+
* Opt out of all tracking
|
|
438
|
+
*/
|
|
439
|
+
optOut(): void;
|
|
440
|
+
/**
|
|
441
|
+
* Opt back in to tracking
|
|
442
|
+
*/
|
|
443
|
+
optIn(): void;
|
|
444
|
+
/**
|
|
445
|
+
* Check if user has opted out
|
|
446
|
+
*/
|
|
447
|
+
isOptedOut(): boolean;
|
|
448
|
+
/**
|
|
449
|
+
* Reset identity (e.g., on logout)
|
|
450
|
+
*/
|
|
451
|
+
reset(): void;
|
|
452
|
+
/**
|
|
453
|
+
* Get current visitor/anonymous ID
|
|
454
|
+
*/
|
|
455
|
+
getVisitorId(): string;
|
|
456
|
+
/**
|
|
457
|
+
* Get identified email address
|
|
458
|
+
*/
|
|
459
|
+
getIdentifiedEmail(): string | null;
|
|
460
|
+
track(eventName: string, properties?: TrackProps): void;
|
|
461
|
+
identify(email: string, traits?: TrackProps): void;
|
|
462
|
+
pageView(): void;
|
|
463
|
+
private getOrSetAnonymousId;
|
|
464
|
+
private sendEvent;
|
|
465
|
+
loadRules(): Promise<void>;
|
|
466
|
+
/**
|
|
467
|
+
* Smart Auto-Detection of Page Type & Context
|
|
468
|
+
* Uses Dynamic Rules + Static Heuristics
|
|
469
|
+
*/
|
|
470
|
+
private detectContext;
|
|
471
|
+
private setupFormListeners;
|
|
472
|
+
private setupHistoryListeners;
|
|
473
|
+
private setCookie;
|
|
474
|
+
private getCookie;
|
|
475
|
+
private log;
|
|
476
|
+
private isDNTEnabled;
|
|
477
|
+
private checkUrlForSubscriber;
|
|
478
|
+
private setupDataAttributeTracking;
|
|
479
|
+
private getStoredEmail;
|
|
480
|
+
private storeEmail;
|
|
481
|
+
private isValidEmail;
|
|
482
|
+
}
|
|
483
|
+
/** Alias for SendmailPixel for SDK consistency */
|
|
484
|
+
declare const Pixel: typeof SendmailPixel;
|
|
485
|
+
/**
|
|
486
|
+
* Create pixel and attach global smp() function
|
|
487
|
+
*/
|
|
488
|
+
declare function createGlobalPixel(config: PixelConfig): SendmailPixel;
|
|
489
|
+
|
|
403
490
|
/**
|
|
404
491
|
* Custom error classes for SendMailOS SDK
|
|
405
492
|
*/
|
|
@@ -477,4 +564,4 @@ declare function constructWebhookEvent<T = unknown>(payload: string, headers: {
|
|
|
477
564
|
timestamp: string;
|
|
478
565
|
}, secret: string): T;
|
|
479
566
|
|
|
480
|
-
export { type ApiError, AuthenticationError, type CreateDomainRequest, type CreateDomainResponse, type CreateSubscriberRequest, type CreateSubscriberResponse, type CreateWebhookRequest, type DnsRecord, type Domain, type ListDomainsResponse, type ListSubscribersRequest, type ListSubscribersResponse, NotFoundError, RateLimitError, type SendCampaignRequest, type SendCampaignResponse, type SendEmailRequest, type SendEmailResponse, SendMailOS, SendMailOSError, type SendMailOSOptions, type Subscriber, ValidationError, type VerifyWebhookParams, type Webhook, type WebhookEvent, type WebhookEventType, constructWebhookEvent, SendMailOS as default, verifyWebhookSignature, verifyWebhookSignatureAsync };
|
|
567
|
+
export { type ApiError, AuthenticationError, type CreateDomainRequest, type CreateDomainResponse, type CreateSubscriberRequest, type CreateSubscriberResponse, type CreateWebhookRequest, type DnsRecord, type Domain, type IdentifyTraits, type ListDomainsResponse, type ListSubscribersRequest, type ListSubscribersResponse, NotFoundError, Pixel, type PixelConfig, type PixelOptions, RateLimitError, type SendCampaignRequest, type SendCampaignResponse, type SendEmailRequest, type SendEmailResponse, SendMailOS, SendMailOSError, type SendMailOSOptions, SendmailPixel, type Subscriber, type TrackEventProperties, type TrackProps, ValidationError, type VerifyWebhookParams, type Webhook, type WebhookEvent, type WebhookEventType, constructWebhookEvent, createGlobalPixel, SendMailOS as default, verifyWebhookSignature, verifyWebhookSignatureAsync };
|
package/dist/index.js
CHANGED
|
@@ -434,6 +434,382 @@ var SendMailOS = class {
|
|
|
434
434
|
}
|
|
435
435
|
};
|
|
436
436
|
|
|
437
|
+
// src/pixel.ts
|
|
438
|
+
var OPT_OUT_KEY = "smp_opt_out";
|
|
439
|
+
var IDENTIFIED_EMAIL_KEY = "smp_identified_email";
|
|
440
|
+
var SendmailPixel = class {
|
|
441
|
+
constructor(config) {
|
|
442
|
+
this.initialized = false;
|
|
443
|
+
this.rules = [];
|
|
444
|
+
this.identifiedEmail = null;
|
|
445
|
+
this.config = {
|
|
446
|
+
endpoint: "https://sendmailos.com/api/pixel/track",
|
|
447
|
+
cookieName: "sm_anon_id",
|
|
448
|
+
debug: false,
|
|
449
|
+
respectDNT: true,
|
|
450
|
+
...config
|
|
451
|
+
};
|
|
452
|
+
this.anonymousId = this.getOrSetAnonymousId();
|
|
453
|
+
this.identifiedEmail = this.getStoredEmail();
|
|
454
|
+
}
|
|
455
|
+
init() {
|
|
456
|
+
if (this.initialized) return;
|
|
457
|
+
if (typeof window === "undefined") {
|
|
458
|
+
return;
|
|
459
|
+
}
|
|
460
|
+
if (this.isOptedOut()) {
|
|
461
|
+
this.log("Tracking disabled (user opted out)");
|
|
462
|
+
return;
|
|
463
|
+
}
|
|
464
|
+
if (this.config.respectDNT && this.isDNTEnabled()) {
|
|
465
|
+
this.log("Tracking disabled (Do Not Track enabled)");
|
|
466
|
+
return;
|
|
467
|
+
}
|
|
468
|
+
this.initialized = true;
|
|
469
|
+
this.checkUrlForSubscriber();
|
|
470
|
+
this.loadRules();
|
|
471
|
+
this.pageView();
|
|
472
|
+
this.setupFormListeners();
|
|
473
|
+
this.setupHistoryListeners();
|
|
474
|
+
this.setupDataAttributeTracking();
|
|
475
|
+
this.log("Pixel initialized with Token:", this.config.token);
|
|
476
|
+
}
|
|
477
|
+
/**
|
|
478
|
+
* Opt out of all tracking
|
|
479
|
+
*/
|
|
480
|
+
optOut() {
|
|
481
|
+
if (typeof localStorage !== "undefined") {
|
|
482
|
+
localStorage.setItem(OPT_OUT_KEY, "true");
|
|
483
|
+
}
|
|
484
|
+
this.log("User opted out of tracking");
|
|
485
|
+
}
|
|
486
|
+
/**
|
|
487
|
+
* Opt back in to tracking
|
|
488
|
+
*/
|
|
489
|
+
optIn() {
|
|
490
|
+
if (typeof localStorage !== "undefined") {
|
|
491
|
+
localStorage.removeItem(OPT_OUT_KEY);
|
|
492
|
+
}
|
|
493
|
+
if (!this.initialized && typeof window !== "undefined") {
|
|
494
|
+
this.init();
|
|
495
|
+
}
|
|
496
|
+
this.log("User opted in to tracking");
|
|
497
|
+
}
|
|
498
|
+
/**
|
|
499
|
+
* Check if user has opted out
|
|
500
|
+
*/
|
|
501
|
+
isOptedOut() {
|
|
502
|
+
if (typeof localStorage === "undefined") return false;
|
|
503
|
+
return localStorage.getItem(OPT_OUT_KEY) === "true";
|
|
504
|
+
}
|
|
505
|
+
/**
|
|
506
|
+
* Reset identity (e.g., on logout)
|
|
507
|
+
*/
|
|
508
|
+
reset() {
|
|
509
|
+
this.identifiedEmail = null;
|
|
510
|
+
if (typeof localStorage !== "undefined") {
|
|
511
|
+
localStorage.removeItem(IDENTIFIED_EMAIL_KEY);
|
|
512
|
+
}
|
|
513
|
+
this.anonymousId = crypto.randomUUID();
|
|
514
|
+
this.setCookie(this.config.cookieName, this.anonymousId, 365);
|
|
515
|
+
this.log("Identity reset");
|
|
516
|
+
}
|
|
517
|
+
/**
|
|
518
|
+
* Get current visitor/anonymous ID
|
|
519
|
+
*/
|
|
520
|
+
getVisitorId() {
|
|
521
|
+
return this.anonymousId;
|
|
522
|
+
}
|
|
523
|
+
/**
|
|
524
|
+
* Get identified email address
|
|
525
|
+
*/
|
|
526
|
+
getIdentifiedEmail() {
|
|
527
|
+
return this.identifiedEmail;
|
|
528
|
+
}
|
|
529
|
+
track(eventName, properties = {}) {
|
|
530
|
+
this.sendEvent("track", {
|
|
531
|
+
event_name: eventName,
|
|
532
|
+
properties
|
|
533
|
+
});
|
|
534
|
+
}
|
|
535
|
+
identify(email, traits = {}) {
|
|
536
|
+
if (this.isOptedOut()) return;
|
|
537
|
+
this.identifiedEmail = email;
|
|
538
|
+
this.storeEmail(email);
|
|
539
|
+
this.sendEvent("identify", {
|
|
540
|
+
email,
|
|
541
|
+
traits
|
|
542
|
+
});
|
|
543
|
+
}
|
|
544
|
+
pageView() {
|
|
545
|
+
this.track("page_view", {
|
|
546
|
+
path: window.location.pathname,
|
|
547
|
+
title: document.title,
|
|
548
|
+
referrer: document.referrer,
|
|
549
|
+
url: window.location.href
|
|
550
|
+
});
|
|
551
|
+
}
|
|
552
|
+
// --- INTERNAL HELPERS ---
|
|
553
|
+
getOrSetAnonymousId() {
|
|
554
|
+
if (typeof document === "undefined") return "";
|
|
555
|
+
let id = this.getCookie(this.config.cookieName);
|
|
556
|
+
if (!id) {
|
|
557
|
+
id = crypto.randomUUID();
|
|
558
|
+
this.setCookie(this.config.cookieName, id, 365);
|
|
559
|
+
}
|
|
560
|
+
return id;
|
|
561
|
+
}
|
|
562
|
+
sendEvent(type, payload) {
|
|
563
|
+
if (typeof window === "undefined") return;
|
|
564
|
+
const smartContext = this.detectContext();
|
|
565
|
+
const body = {
|
|
566
|
+
type,
|
|
567
|
+
token: this.config.token,
|
|
568
|
+
// Send Token
|
|
569
|
+
anonymous_id: this.anonymousId,
|
|
570
|
+
url: window.location.href,
|
|
571
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
572
|
+
...payload
|
|
573
|
+
};
|
|
574
|
+
const context = {
|
|
575
|
+
userAgent: navigator.userAgent,
|
|
576
|
+
locale: navigator.language,
|
|
577
|
+
screen: { width: window.screen.width, height: window.screen.height },
|
|
578
|
+
search: window.location.search,
|
|
579
|
+
title: document.title,
|
|
580
|
+
referrer: document.referrer,
|
|
581
|
+
...smartContext
|
|
582
|
+
// Merge smart context
|
|
583
|
+
};
|
|
584
|
+
const finalBody = { ...body, context };
|
|
585
|
+
if (navigator.sendBeacon && type === "track") {
|
|
586
|
+
const blob = new Blob([JSON.stringify(finalBody)], { type: "application/json" });
|
|
587
|
+
navigator.sendBeacon(this.config.endpoint, blob);
|
|
588
|
+
} else {
|
|
589
|
+
fetch(this.config.endpoint, {
|
|
590
|
+
method: "POST",
|
|
591
|
+
headers: { "Content-Type": "application/json" },
|
|
592
|
+
body: JSON.stringify(finalBody),
|
|
593
|
+
keepalive: true
|
|
594
|
+
}).catch((err) => {
|
|
595
|
+
if (this.config.debug) console.error("[Pixel Error]", err);
|
|
596
|
+
});
|
|
597
|
+
}
|
|
598
|
+
this.log(`Event Sent [${type}]`, body);
|
|
599
|
+
}
|
|
600
|
+
// Call this after init to load rules
|
|
601
|
+
async loadRules() {
|
|
602
|
+
if (typeof window === "undefined") return;
|
|
603
|
+
try {
|
|
604
|
+
const res = await fetch(`${this.config.endpoint?.replace("/track", "")}/rules?token=${this.config.token}`);
|
|
605
|
+
if (res.ok) {
|
|
606
|
+
const data = await res.json();
|
|
607
|
+
this.rules = data.rules || [];
|
|
608
|
+
}
|
|
609
|
+
} catch (e) {
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
/**
|
|
613
|
+
* Smart Auto-Detection of Page Type & Context
|
|
614
|
+
* Uses Dynamic Rules + Static Heuristics
|
|
615
|
+
*/
|
|
616
|
+
detectContext() {
|
|
617
|
+
if (typeof document === "undefined") return {};
|
|
618
|
+
const path = window.location.pathname.toLowerCase();
|
|
619
|
+
let context = {
|
|
620
|
+
page_type: "general",
|
|
621
|
+
// Default
|
|
622
|
+
topics: []
|
|
623
|
+
};
|
|
624
|
+
for (const rule of this.rules) {
|
|
625
|
+
let matched = false;
|
|
626
|
+
try {
|
|
627
|
+
if (rule.match_type === "exact" && path === rule.url_pattern) matched = true;
|
|
628
|
+
else if (rule.match_type === "contains" && path.includes(rule.url_pattern)) matched = true;
|
|
629
|
+
else if (rule.match_type === "regex" && new RegExp(rule.url_pattern).test(path)) matched = true;
|
|
630
|
+
} catch (e) {
|
|
631
|
+
}
|
|
632
|
+
if (matched) {
|
|
633
|
+
context.page_type = rule.page_type;
|
|
634
|
+
if (rule.selectors) {
|
|
635
|
+
for (const [key, selector] of Object.entries(rule.selectors)) {
|
|
636
|
+
const el = document.querySelector(selector);
|
|
637
|
+
if (el) {
|
|
638
|
+
const val = el.value || el.textContent || el.getAttribute("content");
|
|
639
|
+
if (val) context[key] = val.trim();
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
return context;
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
if (path.match(/\/(cart|basket|bag)/)) context.page_type = "cart";
|
|
647
|
+
else if (path.match(/\/(checkout|payment|order)/)) context.page_type = "checkout";
|
|
648
|
+
else if (path.match(/\/(product|item|p)\//)) context.page_type = "product";
|
|
649
|
+
else if (path.match(/\/(category|c|collection)\//)) context.page_type = "category";
|
|
650
|
+
else if (path.match(/\/(blog|article|post|news)/)) context.page_type = "content";
|
|
651
|
+
else if (path.match(/\/(login|signin)/)) context.page_type = "auth";
|
|
652
|
+
else if (path.match(/\/(signup|register)/)) context.page_type = "auth";
|
|
653
|
+
else if (path.match(/\/(pricing|plans)/)) context.page_type = "pricing";
|
|
654
|
+
else if (path.match(/\/(thank-you|confirmation|success)/)) context.page_type = "purchase_success";
|
|
655
|
+
const ogType = document.querySelector('meta[property="og:type"]')?.getAttribute("content");
|
|
656
|
+
if (ogType === "product") {
|
|
657
|
+
context.page_type = "product";
|
|
658
|
+
const price = document.querySelector('meta[property="product:price:amount"]')?.getAttribute("content");
|
|
659
|
+
if (price) context.product_price = price;
|
|
660
|
+
const currency = document.querySelector('meta[property="product:price:currency"]')?.getAttribute("content");
|
|
661
|
+
if (currency) context.currency = currency;
|
|
662
|
+
}
|
|
663
|
+
if (document.querySelector(".cart-total") || document.querySelector("#cart-summary")) {
|
|
664
|
+
context.page_type = "cart";
|
|
665
|
+
}
|
|
666
|
+
if (document.querySelector("#card-element") || document.querySelector('input[name="card_number"]')) {
|
|
667
|
+
context.page_type = "checkout";
|
|
668
|
+
}
|
|
669
|
+
const text = document.body.innerText.toLowerCase().slice(0, 2e3);
|
|
670
|
+
if (text.includes("out of stock")) context.stock_status = "out_of_stock";
|
|
671
|
+
if (text.includes("limited time")) context.urgency = "high";
|
|
672
|
+
return context;
|
|
673
|
+
}
|
|
674
|
+
setupFormListeners() {
|
|
675
|
+
if (typeof document === "undefined") return;
|
|
676
|
+
document.addEventListener("submit", (e) => {
|
|
677
|
+
const form = e.target;
|
|
678
|
+
if (!form) return;
|
|
679
|
+
const emailInput = form.querySelector('input[type="email"]');
|
|
680
|
+
if (emailInput && emailInput.value) {
|
|
681
|
+
this.log("Auto-detected email form submission", emailInput.value);
|
|
682
|
+
this.identify(emailInput.value);
|
|
683
|
+
}
|
|
684
|
+
}, true);
|
|
685
|
+
}
|
|
686
|
+
setupHistoryListeners() {
|
|
687
|
+
if (typeof window === "undefined") return;
|
|
688
|
+
const pushState = history.pushState;
|
|
689
|
+
history.pushState = (...args) => {
|
|
690
|
+
pushState.apply(history, args);
|
|
691
|
+
this.pageView();
|
|
692
|
+
};
|
|
693
|
+
window.addEventListener("popstate", () => {
|
|
694
|
+
this.pageView();
|
|
695
|
+
});
|
|
696
|
+
}
|
|
697
|
+
// --- COOKIE UTILS ---
|
|
698
|
+
setCookie(name, value, days) {
|
|
699
|
+
const d = /* @__PURE__ */ new Date();
|
|
700
|
+
d.setTime(d.getTime() + days * 24 * 60 * 60 * 1e3);
|
|
701
|
+
const expires = "expires=" + d.toUTCString();
|
|
702
|
+
document.cookie = name + "=" + value + ";" + expires + ";path=/;SameSite=Lax";
|
|
703
|
+
}
|
|
704
|
+
getCookie(name) {
|
|
705
|
+
const nameEQ = name + "=";
|
|
706
|
+
const ca = document.cookie.split(";");
|
|
707
|
+
for (let i = 0; i < ca.length; i++) {
|
|
708
|
+
let c = ca[i];
|
|
709
|
+
while (c.charAt(0) == " ") c = c.substring(1, c.length);
|
|
710
|
+
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
|
|
711
|
+
}
|
|
712
|
+
return null;
|
|
713
|
+
}
|
|
714
|
+
log(...args) {
|
|
715
|
+
if (this.config.debug) {
|
|
716
|
+
console.log("[SendmailPixel]", ...args);
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
isDNTEnabled() {
|
|
720
|
+
if (typeof navigator === "undefined") return false;
|
|
721
|
+
return navigator.doNotTrack === "1" || window.doNotTrack === "1";
|
|
722
|
+
}
|
|
723
|
+
checkUrlForSubscriber() {
|
|
724
|
+
if (typeof window === "undefined") return;
|
|
725
|
+
const params = new URLSearchParams(window.location.search);
|
|
726
|
+
const subscriberEmail = params.get("smp_email");
|
|
727
|
+
const subscriberId = params.get("smp_sub");
|
|
728
|
+
if (subscriberEmail) {
|
|
729
|
+
try {
|
|
730
|
+
const email = atob(subscriberEmail);
|
|
731
|
+
if (this.isValidEmail(email)) {
|
|
732
|
+
this.identify(email);
|
|
733
|
+
}
|
|
734
|
+
} catch {
|
|
735
|
+
if (this.isValidEmail(subscriberEmail)) {
|
|
736
|
+
this.identify(subscriberEmail);
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
} else if (subscriberId) {
|
|
740
|
+
this.track("email_link_clicked", { subscriber_id: subscriberId });
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
setupDataAttributeTracking() {
|
|
744
|
+
if (typeof document === "undefined") return;
|
|
745
|
+
document.addEventListener("click", (e) => {
|
|
746
|
+
const target = e.target;
|
|
747
|
+
const tracked = target.closest("[data-smp-track]");
|
|
748
|
+
if (tracked) {
|
|
749
|
+
const eventName = tracked.getAttribute("data-smp-track");
|
|
750
|
+
const properties = {};
|
|
751
|
+
Array.from(tracked.attributes).forEach((attr) => {
|
|
752
|
+
if (attr.name.startsWith("data-smp-track-") && attr.name !== "data-smp-track") {
|
|
753
|
+
const propName = attr.name.replace("data-smp-track-", "").replace(/-/g, "_");
|
|
754
|
+
properties[propName] = attr.value;
|
|
755
|
+
}
|
|
756
|
+
});
|
|
757
|
+
if (eventName) {
|
|
758
|
+
this.track(eventName, properties);
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
});
|
|
762
|
+
}
|
|
763
|
+
getStoredEmail() {
|
|
764
|
+
if (typeof localStorage === "undefined") return null;
|
|
765
|
+
return localStorage.getItem(IDENTIFIED_EMAIL_KEY);
|
|
766
|
+
}
|
|
767
|
+
storeEmail(email) {
|
|
768
|
+
if (typeof localStorage !== "undefined") {
|
|
769
|
+
localStorage.setItem(IDENTIFIED_EMAIL_KEY, email);
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
isValidEmail(email) {
|
|
773
|
+
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
|
|
774
|
+
}
|
|
775
|
+
};
|
|
776
|
+
var Pixel = SendmailPixel;
|
|
777
|
+
function createGlobalPixel(config) {
|
|
778
|
+
const pixel = new SendmailPixel(config);
|
|
779
|
+
if (typeof window !== "undefined") {
|
|
780
|
+
const smpFunction = (method, ...args) => {
|
|
781
|
+
switch (method) {
|
|
782
|
+
case "track":
|
|
783
|
+
pixel.track(args[0], args[1]);
|
|
784
|
+
return void 0;
|
|
785
|
+
case "identify":
|
|
786
|
+
pixel.identify(args[0], args[1]);
|
|
787
|
+
return void 0;
|
|
788
|
+
case "page":
|
|
789
|
+
pixel.pageView();
|
|
790
|
+
return void 0;
|
|
791
|
+
case "optOut":
|
|
792
|
+
pixel.optOut();
|
|
793
|
+
return void 0;
|
|
794
|
+
case "optIn":
|
|
795
|
+
pixel.optIn();
|
|
796
|
+
return void 0;
|
|
797
|
+
case "isOptedOut":
|
|
798
|
+
return pixel.isOptedOut();
|
|
799
|
+
case "reset":
|
|
800
|
+
pixel.reset();
|
|
801
|
+
return void 0;
|
|
802
|
+
default:
|
|
803
|
+
console.warn(`[SendmailPixel] Unknown method: ${method}`);
|
|
804
|
+
return void 0;
|
|
805
|
+
}
|
|
806
|
+
};
|
|
807
|
+
window.smp = smpFunction;
|
|
808
|
+
}
|
|
809
|
+
pixel.init();
|
|
810
|
+
return pixel;
|
|
811
|
+
}
|
|
812
|
+
|
|
437
813
|
// src/utils/webhook.ts
|
|
438
814
|
function verifyWebhookSignature(params) {
|
|
439
815
|
const { payload, signature, timestamp, secret, tolerance = 300 } = params;
|
|
@@ -526,11 +902,14 @@ function constructWebhookEvent(payload, headers, secret) {
|
|
|
526
902
|
|
|
527
903
|
exports.AuthenticationError = AuthenticationError;
|
|
528
904
|
exports.NotFoundError = NotFoundError;
|
|
905
|
+
exports.Pixel = Pixel;
|
|
529
906
|
exports.RateLimitError = RateLimitError;
|
|
530
907
|
exports.SendMailOS = SendMailOS;
|
|
531
908
|
exports.SendMailOSError = SendMailOSError;
|
|
909
|
+
exports.SendmailPixel = SendmailPixel;
|
|
532
910
|
exports.ValidationError = ValidationError;
|
|
533
911
|
exports.constructWebhookEvent = constructWebhookEvent;
|
|
912
|
+
exports.createGlobalPixel = createGlobalPixel;
|
|
534
913
|
exports.default = SendMailOS;
|
|
535
914
|
exports.verifyWebhookSignature = verifyWebhookSignature;
|
|
536
915
|
exports.verifyWebhookSignatureAsync = verifyWebhookSignatureAsync;
|