saasco-sdk 0.1.40 → 0.1.42
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/index.cjs.js +293 -539
- package/index.esm.js +292 -535
- package/package.json +3 -2
- package/src/lib/analytics.d.ts +2 -1
- package/src/lib/integrations/index.d.ts +1 -0
- package/src/lib/integrations/tiktok-pixel.d.ts +59 -0
package/index.esm.js
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { __awaiter } from 'tslib';
|
|
2
2
|
import { isValid, parse } from 'psl';
|
|
3
|
-
import
|
|
4
|
-
import require$$1 from 'buffer';
|
|
3
|
+
import { sha256 } from 'js-sha256';
|
|
5
4
|
import { v4 } from '@lukeed/uuid';
|
|
6
5
|
import { z } from 'zod';
|
|
7
6
|
|
|
8
|
-
var version = "0.1.
|
|
7
|
+
var version = "0.1.42";
|
|
9
8
|
|
|
10
9
|
const timezones = {
|
|
11
10
|
'Asia/Barnaul': 'RU',
|
|
@@ -552,535 +551,8 @@ function getBrowserContext() {
|
|
|
552
551
|
};
|
|
553
552
|
}
|
|
554
553
|
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
var sha256 = {exports: {}};
|
|
558
|
-
|
|
559
|
-
/**
|
|
560
|
-
* [js-sha256]{@link https://github.com/emn178/js-sha256}
|
|
561
|
-
*
|
|
562
|
-
* @version 0.11.1
|
|
563
|
-
* @author Chen, Yi-Cyuan [emn178@gmail.com]
|
|
564
|
-
* @copyright Chen, Yi-Cyuan 2014-2025
|
|
565
|
-
* @license MIT
|
|
566
|
-
*/
|
|
567
|
-
|
|
568
|
-
(function (module) {
|
|
569
|
-
/*jslint bitwise: true */
|
|
570
|
-
(function () {
|
|
571
|
-
|
|
572
|
-
var ERROR = 'input is invalid type';
|
|
573
|
-
var WINDOW = typeof window === 'object';
|
|
574
|
-
var root = WINDOW ? window : {};
|
|
575
|
-
if (root.JS_SHA256_NO_WINDOW) {
|
|
576
|
-
WINDOW = false;
|
|
577
|
-
}
|
|
578
|
-
var WEB_WORKER = !WINDOW && typeof self === 'object';
|
|
579
|
-
var NODE_JS = !root.JS_SHA256_NO_NODE_JS && typeof process === 'object' && process.versions && process.versions.node && process.type != 'renderer';
|
|
580
|
-
if (NODE_JS) {
|
|
581
|
-
root = commonjsGlobal;
|
|
582
|
-
} else if (WEB_WORKER) {
|
|
583
|
-
root = self;
|
|
584
|
-
}
|
|
585
|
-
var COMMON_JS = !root.JS_SHA256_NO_COMMON_JS && 'object' === 'object' && module.exports;
|
|
586
|
-
var ARRAY_BUFFER = !root.JS_SHA256_NO_ARRAY_BUFFER && typeof ArrayBuffer !== 'undefined';
|
|
587
|
-
var HEX_CHARS = '0123456789abcdef'.split('');
|
|
588
|
-
var EXTRA = [-2147483648, 8388608, 32768, 128];
|
|
589
|
-
var SHIFT = [24, 16, 8, 0];
|
|
590
|
-
var K = [
|
|
591
|
-
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
|
592
|
-
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
|
593
|
-
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
|
594
|
-
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
|
|
595
|
-
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
|
|
596
|
-
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
|
|
597
|
-
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
|
|
598
|
-
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
|
|
599
|
-
];
|
|
600
|
-
var OUTPUT_TYPES = ['hex', 'array', 'digest', 'arrayBuffer'];
|
|
601
|
-
|
|
602
|
-
var blocks = [];
|
|
603
|
-
|
|
604
|
-
if (root.JS_SHA256_NO_NODE_JS || !Array.isArray) {
|
|
605
|
-
Array.isArray = function (obj) {
|
|
606
|
-
return Object.prototype.toString.call(obj) === '[object Array]';
|
|
607
|
-
};
|
|
608
|
-
}
|
|
609
|
-
|
|
610
|
-
if (ARRAY_BUFFER && (root.JS_SHA256_NO_ARRAY_BUFFER_IS_VIEW || !ArrayBuffer.isView)) {
|
|
611
|
-
ArrayBuffer.isView = function (obj) {
|
|
612
|
-
return typeof obj === 'object' && obj.buffer && obj.buffer.constructor === ArrayBuffer;
|
|
613
|
-
};
|
|
614
|
-
}
|
|
615
|
-
|
|
616
|
-
var createOutputMethod = function (outputType, is224) {
|
|
617
|
-
return function (message) {
|
|
618
|
-
return new Sha256(is224, true).update(message)[outputType]();
|
|
619
|
-
};
|
|
620
|
-
};
|
|
621
|
-
|
|
622
|
-
var createMethod = function (is224) {
|
|
623
|
-
var method = createOutputMethod('hex', is224);
|
|
624
|
-
if (NODE_JS) {
|
|
625
|
-
method = nodeWrap(method, is224);
|
|
626
|
-
}
|
|
627
|
-
method.create = function () {
|
|
628
|
-
return new Sha256(is224);
|
|
629
|
-
};
|
|
630
|
-
method.update = function (message) {
|
|
631
|
-
return method.create().update(message);
|
|
632
|
-
};
|
|
633
|
-
for (var i = 0; i < OUTPUT_TYPES.length; ++i) {
|
|
634
|
-
var type = OUTPUT_TYPES[i];
|
|
635
|
-
method[type] = createOutputMethod(type, is224);
|
|
636
|
-
}
|
|
637
|
-
return method;
|
|
638
|
-
};
|
|
639
|
-
|
|
640
|
-
var nodeWrap = function (method, is224) {
|
|
641
|
-
var crypto = require$$0;
|
|
642
|
-
var Buffer = require$$1.Buffer;
|
|
643
|
-
var algorithm = is224 ? 'sha224' : 'sha256';
|
|
644
|
-
var bufferFrom;
|
|
645
|
-
if (Buffer.from && !root.JS_SHA256_NO_BUFFER_FROM) {
|
|
646
|
-
bufferFrom = Buffer.from;
|
|
647
|
-
} else {
|
|
648
|
-
bufferFrom = function (message) {
|
|
649
|
-
return new Buffer(message);
|
|
650
|
-
};
|
|
651
|
-
}
|
|
652
|
-
var nodeMethod = function (message) {
|
|
653
|
-
if (typeof message === 'string') {
|
|
654
|
-
return crypto.createHash(algorithm).update(message, 'utf8').digest('hex');
|
|
655
|
-
} else {
|
|
656
|
-
if (message === null || message === undefined) {
|
|
657
|
-
throw new Error(ERROR);
|
|
658
|
-
} else if (message.constructor === ArrayBuffer) {
|
|
659
|
-
message = new Uint8Array(message);
|
|
660
|
-
}
|
|
661
|
-
}
|
|
662
|
-
if (Array.isArray(message) || ArrayBuffer.isView(message) ||
|
|
663
|
-
message.constructor === Buffer) {
|
|
664
|
-
return crypto.createHash(algorithm).update(bufferFrom(message)).digest('hex');
|
|
665
|
-
} else {
|
|
666
|
-
return method(message);
|
|
667
|
-
}
|
|
668
|
-
};
|
|
669
|
-
return nodeMethod;
|
|
670
|
-
};
|
|
671
|
-
|
|
672
|
-
var createHmacOutputMethod = function (outputType, is224) {
|
|
673
|
-
return function (key, message) {
|
|
674
|
-
return new HmacSha256(key, is224, true).update(message)[outputType]();
|
|
675
|
-
};
|
|
676
|
-
};
|
|
677
|
-
|
|
678
|
-
var createHmacMethod = function (is224) {
|
|
679
|
-
var method = createHmacOutputMethod('hex', is224);
|
|
680
|
-
method.create = function (key) {
|
|
681
|
-
return new HmacSha256(key, is224);
|
|
682
|
-
};
|
|
683
|
-
method.update = function (key, message) {
|
|
684
|
-
return method.create(key).update(message);
|
|
685
|
-
};
|
|
686
|
-
for (var i = 0; i < OUTPUT_TYPES.length; ++i) {
|
|
687
|
-
var type = OUTPUT_TYPES[i];
|
|
688
|
-
method[type] = createHmacOutputMethod(type, is224);
|
|
689
|
-
}
|
|
690
|
-
return method;
|
|
691
|
-
};
|
|
692
|
-
|
|
693
|
-
function Sha256(is224, sharedMemory) {
|
|
694
|
-
if (sharedMemory) {
|
|
695
|
-
blocks[0] = blocks[16] = blocks[1] = blocks[2] = blocks[3] =
|
|
696
|
-
blocks[4] = blocks[5] = blocks[6] = blocks[7] =
|
|
697
|
-
blocks[8] = blocks[9] = blocks[10] = blocks[11] =
|
|
698
|
-
blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0;
|
|
699
|
-
this.blocks = blocks;
|
|
700
|
-
} else {
|
|
701
|
-
this.blocks = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
|
|
702
|
-
}
|
|
703
|
-
|
|
704
|
-
if (is224) {
|
|
705
|
-
this.h0 = 0xc1059ed8;
|
|
706
|
-
this.h1 = 0x367cd507;
|
|
707
|
-
this.h2 = 0x3070dd17;
|
|
708
|
-
this.h3 = 0xf70e5939;
|
|
709
|
-
this.h4 = 0xffc00b31;
|
|
710
|
-
this.h5 = 0x68581511;
|
|
711
|
-
this.h6 = 0x64f98fa7;
|
|
712
|
-
this.h7 = 0xbefa4fa4;
|
|
713
|
-
} else { // 256
|
|
714
|
-
this.h0 = 0x6a09e667;
|
|
715
|
-
this.h1 = 0xbb67ae85;
|
|
716
|
-
this.h2 = 0x3c6ef372;
|
|
717
|
-
this.h3 = 0xa54ff53a;
|
|
718
|
-
this.h4 = 0x510e527f;
|
|
719
|
-
this.h5 = 0x9b05688c;
|
|
720
|
-
this.h6 = 0x1f83d9ab;
|
|
721
|
-
this.h7 = 0x5be0cd19;
|
|
722
|
-
}
|
|
723
|
-
|
|
724
|
-
this.block = this.start = this.bytes = this.hBytes = 0;
|
|
725
|
-
this.finalized = this.hashed = false;
|
|
726
|
-
this.first = true;
|
|
727
|
-
this.is224 = is224;
|
|
728
|
-
}
|
|
729
|
-
|
|
730
|
-
Sha256.prototype.update = function (message) {
|
|
731
|
-
if (this.finalized) {
|
|
732
|
-
return;
|
|
733
|
-
}
|
|
734
|
-
var notString, type = typeof message;
|
|
735
|
-
if (type !== 'string') {
|
|
736
|
-
if (type === 'object') {
|
|
737
|
-
if (message === null) {
|
|
738
|
-
throw new Error(ERROR);
|
|
739
|
-
} else if (ARRAY_BUFFER && message.constructor === ArrayBuffer) {
|
|
740
|
-
message = new Uint8Array(message);
|
|
741
|
-
} else if (!Array.isArray(message)) {
|
|
742
|
-
if (!ARRAY_BUFFER || !ArrayBuffer.isView(message)) {
|
|
743
|
-
throw new Error(ERROR);
|
|
744
|
-
}
|
|
745
|
-
}
|
|
746
|
-
} else {
|
|
747
|
-
throw new Error(ERROR);
|
|
748
|
-
}
|
|
749
|
-
notString = true;
|
|
750
|
-
}
|
|
751
|
-
var code, index = 0, i, length = message.length, blocks = this.blocks;
|
|
752
|
-
while (index < length) {
|
|
753
|
-
if (this.hashed) {
|
|
754
|
-
this.hashed = false;
|
|
755
|
-
blocks[0] = this.block;
|
|
756
|
-
this.block = blocks[16] = blocks[1] = blocks[2] = blocks[3] =
|
|
757
|
-
blocks[4] = blocks[5] = blocks[6] = blocks[7] =
|
|
758
|
-
blocks[8] = blocks[9] = blocks[10] = blocks[11] =
|
|
759
|
-
blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0;
|
|
760
|
-
}
|
|
761
|
-
|
|
762
|
-
if (notString) {
|
|
763
|
-
for (i = this.start; index < length && i < 64; ++index) {
|
|
764
|
-
blocks[i >>> 2] |= message[index] << SHIFT[i++ & 3];
|
|
765
|
-
}
|
|
766
|
-
} else {
|
|
767
|
-
for (i = this.start; index < length && i < 64; ++index) {
|
|
768
|
-
code = message.charCodeAt(index);
|
|
769
|
-
if (code < 0x80) {
|
|
770
|
-
blocks[i >>> 2] |= code << SHIFT[i++ & 3];
|
|
771
|
-
} else if (code < 0x800) {
|
|
772
|
-
blocks[i >>> 2] |= (0xc0 | (code >>> 6)) << SHIFT[i++ & 3];
|
|
773
|
-
blocks[i >>> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3];
|
|
774
|
-
} else if (code < 0xd800 || code >= 0xe000) {
|
|
775
|
-
blocks[i >>> 2] |= (0xe0 | (code >>> 12)) << SHIFT[i++ & 3];
|
|
776
|
-
blocks[i >>> 2] |= (0x80 | ((code >>> 6) & 0x3f)) << SHIFT[i++ & 3];
|
|
777
|
-
blocks[i >>> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3];
|
|
778
|
-
} else {
|
|
779
|
-
code = 0x10000 + (((code & 0x3ff) << 10) | (message.charCodeAt(++index) & 0x3ff));
|
|
780
|
-
blocks[i >>> 2] |= (0xf0 | (code >>> 18)) << SHIFT[i++ & 3];
|
|
781
|
-
blocks[i >>> 2] |= (0x80 | ((code >>> 12) & 0x3f)) << SHIFT[i++ & 3];
|
|
782
|
-
blocks[i >>> 2] |= (0x80 | ((code >>> 6) & 0x3f)) << SHIFT[i++ & 3];
|
|
783
|
-
blocks[i >>> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3];
|
|
784
|
-
}
|
|
785
|
-
}
|
|
786
|
-
}
|
|
787
|
-
|
|
788
|
-
this.lastByteIndex = i;
|
|
789
|
-
this.bytes += i - this.start;
|
|
790
|
-
if (i >= 64) {
|
|
791
|
-
this.block = blocks[16];
|
|
792
|
-
this.start = i - 64;
|
|
793
|
-
this.hash();
|
|
794
|
-
this.hashed = true;
|
|
795
|
-
} else {
|
|
796
|
-
this.start = i;
|
|
797
|
-
}
|
|
798
|
-
}
|
|
799
|
-
if (this.bytes > 4294967295) {
|
|
800
|
-
this.hBytes += this.bytes / 4294967296 << 0;
|
|
801
|
-
this.bytes = this.bytes % 4294967296;
|
|
802
|
-
}
|
|
803
|
-
return this;
|
|
804
|
-
};
|
|
805
|
-
|
|
806
|
-
Sha256.prototype.finalize = function () {
|
|
807
|
-
if (this.finalized) {
|
|
808
|
-
return;
|
|
809
|
-
}
|
|
810
|
-
this.finalized = true;
|
|
811
|
-
var blocks = this.blocks, i = this.lastByteIndex;
|
|
812
|
-
blocks[16] = this.block;
|
|
813
|
-
blocks[i >>> 2] |= EXTRA[i & 3];
|
|
814
|
-
this.block = blocks[16];
|
|
815
|
-
if (i >= 56) {
|
|
816
|
-
if (!this.hashed) {
|
|
817
|
-
this.hash();
|
|
818
|
-
}
|
|
819
|
-
blocks[0] = this.block;
|
|
820
|
-
blocks[16] = blocks[1] = blocks[2] = blocks[3] =
|
|
821
|
-
blocks[4] = blocks[5] = blocks[6] = blocks[7] =
|
|
822
|
-
blocks[8] = blocks[9] = blocks[10] = blocks[11] =
|
|
823
|
-
blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0;
|
|
824
|
-
}
|
|
825
|
-
blocks[14] = this.hBytes << 3 | this.bytes >>> 29;
|
|
826
|
-
blocks[15] = this.bytes << 3;
|
|
827
|
-
this.hash();
|
|
828
|
-
};
|
|
829
|
-
|
|
830
|
-
Sha256.prototype.hash = function () {
|
|
831
|
-
var a = this.h0, b = this.h1, c = this.h2, d = this.h3, e = this.h4, f = this.h5, g = this.h6,
|
|
832
|
-
h = this.h7, blocks = this.blocks, j, s0, s1, maj, t1, t2, ch, ab, da, cd, bc;
|
|
833
|
-
|
|
834
|
-
for (j = 16; j < 64; ++j) {
|
|
835
|
-
// rightrotate
|
|
836
|
-
t1 = blocks[j - 15];
|
|
837
|
-
s0 = ((t1 >>> 7) | (t1 << 25)) ^ ((t1 >>> 18) | (t1 << 14)) ^ (t1 >>> 3);
|
|
838
|
-
t1 = blocks[j - 2];
|
|
839
|
-
s1 = ((t1 >>> 17) | (t1 << 15)) ^ ((t1 >>> 19) | (t1 << 13)) ^ (t1 >>> 10);
|
|
840
|
-
blocks[j] = blocks[j - 16] + s0 + blocks[j - 7] + s1 << 0;
|
|
841
|
-
}
|
|
842
|
-
|
|
843
|
-
bc = b & c;
|
|
844
|
-
for (j = 0; j < 64; j += 4) {
|
|
845
|
-
if (this.first) {
|
|
846
|
-
if (this.is224) {
|
|
847
|
-
ab = 300032;
|
|
848
|
-
t1 = blocks[0] - 1413257819;
|
|
849
|
-
h = t1 - 150054599 << 0;
|
|
850
|
-
d = t1 + 24177077 << 0;
|
|
851
|
-
} else {
|
|
852
|
-
ab = 704751109;
|
|
853
|
-
t1 = blocks[0] - 210244248;
|
|
854
|
-
h = t1 - 1521486534 << 0;
|
|
855
|
-
d = t1 + 143694565 << 0;
|
|
856
|
-
}
|
|
857
|
-
this.first = false;
|
|
858
|
-
} else {
|
|
859
|
-
s0 = ((a >>> 2) | (a << 30)) ^ ((a >>> 13) | (a << 19)) ^ ((a >>> 22) | (a << 10));
|
|
860
|
-
s1 = ((e >>> 6) | (e << 26)) ^ ((e >>> 11) | (e << 21)) ^ ((e >>> 25) | (e << 7));
|
|
861
|
-
ab = a & b;
|
|
862
|
-
maj = ab ^ (a & c) ^ bc;
|
|
863
|
-
ch = (e & f) ^ (~e & g);
|
|
864
|
-
t1 = h + s1 + ch + K[j] + blocks[j];
|
|
865
|
-
t2 = s0 + maj;
|
|
866
|
-
h = d + t1 << 0;
|
|
867
|
-
d = t1 + t2 << 0;
|
|
868
|
-
}
|
|
869
|
-
s0 = ((d >>> 2) | (d << 30)) ^ ((d >>> 13) | (d << 19)) ^ ((d >>> 22) | (d << 10));
|
|
870
|
-
s1 = ((h >>> 6) | (h << 26)) ^ ((h >>> 11) | (h << 21)) ^ ((h >>> 25) | (h << 7));
|
|
871
|
-
da = d & a;
|
|
872
|
-
maj = da ^ (d & b) ^ ab;
|
|
873
|
-
ch = (h & e) ^ (~h & f);
|
|
874
|
-
t1 = g + s1 + ch + K[j + 1] + blocks[j + 1];
|
|
875
|
-
t2 = s0 + maj;
|
|
876
|
-
g = c + t1 << 0;
|
|
877
|
-
c = t1 + t2 << 0;
|
|
878
|
-
s0 = ((c >>> 2) | (c << 30)) ^ ((c >>> 13) | (c << 19)) ^ ((c >>> 22) | (c << 10));
|
|
879
|
-
s1 = ((g >>> 6) | (g << 26)) ^ ((g >>> 11) | (g << 21)) ^ ((g >>> 25) | (g << 7));
|
|
880
|
-
cd = c & d;
|
|
881
|
-
maj = cd ^ (c & a) ^ da;
|
|
882
|
-
ch = (g & h) ^ (~g & e);
|
|
883
|
-
t1 = f + s1 + ch + K[j + 2] + blocks[j + 2];
|
|
884
|
-
t2 = s0 + maj;
|
|
885
|
-
f = b + t1 << 0;
|
|
886
|
-
b = t1 + t2 << 0;
|
|
887
|
-
s0 = ((b >>> 2) | (b << 30)) ^ ((b >>> 13) | (b << 19)) ^ ((b >>> 22) | (b << 10));
|
|
888
|
-
s1 = ((f >>> 6) | (f << 26)) ^ ((f >>> 11) | (f << 21)) ^ ((f >>> 25) | (f << 7));
|
|
889
|
-
bc = b & c;
|
|
890
|
-
maj = bc ^ (b & d) ^ cd;
|
|
891
|
-
ch = (f & g) ^ (~f & h);
|
|
892
|
-
t1 = e + s1 + ch + K[j + 3] + blocks[j + 3];
|
|
893
|
-
t2 = s0 + maj;
|
|
894
|
-
e = a + t1 << 0;
|
|
895
|
-
a = t1 + t2 << 0;
|
|
896
|
-
this.chromeBugWorkAround = true;
|
|
897
|
-
}
|
|
898
|
-
|
|
899
|
-
this.h0 = this.h0 + a << 0;
|
|
900
|
-
this.h1 = this.h1 + b << 0;
|
|
901
|
-
this.h2 = this.h2 + c << 0;
|
|
902
|
-
this.h3 = this.h3 + d << 0;
|
|
903
|
-
this.h4 = this.h4 + e << 0;
|
|
904
|
-
this.h5 = this.h5 + f << 0;
|
|
905
|
-
this.h6 = this.h6 + g << 0;
|
|
906
|
-
this.h7 = this.h7 + h << 0;
|
|
907
|
-
};
|
|
908
|
-
|
|
909
|
-
Sha256.prototype.hex = function () {
|
|
910
|
-
this.finalize();
|
|
911
|
-
|
|
912
|
-
var h0 = this.h0, h1 = this.h1, h2 = this.h2, h3 = this.h3, h4 = this.h4, h5 = this.h5,
|
|
913
|
-
h6 = this.h6, h7 = this.h7;
|
|
914
|
-
|
|
915
|
-
var hex = HEX_CHARS[(h0 >>> 28) & 0x0F] + HEX_CHARS[(h0 >>> 24) & 0x0F] +
|
|
916
|
-
HEX_CHARS[(h0 >>> 20) & 0x0F] + HEX_CHARS[(h0 >>> 16) & 0x0F] +
|
|
917
|
-
HEX_CHARS[(h0 >>> 12) & 0x0F] + HEX_CHARS[(h0 >>> 8) & 0x0F] +
|
|
918
|
-
HEX_CHARS[(h0 >>> 4) & 0x0F] + HEX_CHARS[h0 & 0x0F] +
|
|
919
|
-
HEX_CHARS[(h1 >>> 28) & 0x0F] + HEX_CHARS[(h1 >>> 24) & 0x0F] +
|
|
920
|
-
HEX_CHARS[(h1 >>> 20) & 0x0F] + HEX_CHARS[(h1 >>> 16) & 0x0F] +
|
|
921
|
-
HEX_CHARS[(h1 >>> 12) & 0x0F] + HEX_CHARS[(h1 >>> 8) & 0x0F] +
|
|
922
|
-
HEX_CHARS[(h1 >>> 4) & 0x0F] + HEX_CHARS[h1 & 0x0F] +
|
|
923
|
-
HEX_CHARS[(h2 >>> 28) & 0x0F] + HEX_CHARS[(h2 >>> 24) & 0x0F] +
|
|
924
|
-
HEX_CHARS[(h2 >>> 20) & 0x0F] + HEX_CHARS[(h2 >>> 16) & 0x0F] +
|
|
925
|
-
HEX_CHARS[(h2 >>> 12) & 0x0F] + HEX_CHARS[(h2 >>> 8) & 0x0F] +
|
|
926
|
-
HEX_CHARS[(h2 >>> 4) & 0x0F] + HEX_CHARS[h2 & 0x0F] +
|
|
927
|
-
HEX_CHARS[(h3 >>> 28) & 0x0F] + HEX_CHARS[(h3 >>> 24) & 0x0F] +
|
|
928
|
-
HEX_CHARS[(h3 >>> 20) & 0x0F] + HEX_CHARS[(h3 >>> 16) & 0x0F] +
|
|
929
|
-
HEX_CHARS[(h3 >>> 12) & 0x0F] + HEX_CHARS[(h3 >>> 8) & 0x0F] +
|
|
930
|
-
HEX_CHARS[(h3 >>> 4) & 0x0F] + HEX_CHARS[h3 & 0x0F] +
|
|
931
|
-
HEX_CHARS[(h4 >>> 28) & 0x0F] + HEX_CHARS[(h4 >>> 24) & 0x0F] +
|
|
932
|
-
HEX_CHARS[(h4 >>> 20) & 0x0F] + HEX_CHARS[(h4 >>> 16) & 0x0F] +
|
|
933
|
-
HEX_CHARS[(h4 >>> 12) & 0x0F] + HEX_CHARS[(h4 >>> 8) & 0x0F] +
|
|
934
|
-
HEX_CHARS[(h4 >>> 4) & 0x0F] + HEX_CHARS[h4 & 0x0F] +
|
|
935
|
-
HEX_CHARS[(h5 >>> 28) & 0x0F] + HEX_CHARS[(h5 >>> 24) & 0x0F] +
|
|
936
|
-
HEX_CHARS[(h5 >>> 20) & 0x0F] + HEX_CHARS[(h5 >>> 16) & 0x0F] +
|
|
937
|
-
HEX_CHARS[(h5 >>> 12) & 0x0F] + HEX_CHARS[(h5 >>> 8) & 0x0F] +
|
|
938
|
-
HEX_CHARS[(h5 >>> 4) & 0x0F] + HEX_CHARS[h5 & 0x0F] +
|
|
939
|
-
HEX_CHARS[(h6 >>> 28) & 0x0F] + HEX_CHARS[(h6 >>> 24) & 0x0F] +
|
|
940
|
-
HEX_CHARS[(h6 >>> 20) & 0x0F] + HEX_CHARS[(h6 >>> 16) & 0x0F] +
|
|
941
|
-
HEX_CHARS[(h6 >>> 12) & 0x0F] + HEX_CHARS[(h6 >>> 8) & 0x0F] +
|
|
942
|
-
HEX_CHARS[(h6 >>> 4) & 0x0F] + HEX_CHARS[h6 & 0x0F];
|
|
943
|
-
if (!this.is224) {
|
|
944
|
-
hex += HEX_CHARS[(h7 >>> 28) & 0x0F] + HEX_CHARS[(h7 >>> 24) & 0x0F] +
|
|
945
|
-
HEX_CHARS[(h7 >>> 20) & 0x0F] + HEX_CHARS[(h7 >>> 16) & 0x0F] +
|
|
946
|
-
HEX_CHARS[(h7 >>> 12) & 0x0F] + HEX_CHARS[(h7 >>> 8) & 0x0F] +
|
|
947
|
-
HEX_CHARS[(h7 >>> 4) & 0x0F] + HEX_CHARS[h7 & 0x0F];
|
|
948
|
-
}
|
|
949
|
-
return hex;
|
|
950
|
-
};
|
|
951
|
-
|
|
952
|
-
Sha256.prototype.toString = Sha256.prototype.hex;
|
|
953
|
-
|
|
954
|
-
Sha256.prototype.digest = function () {
|
|
955
|
-
this.finalize();
|
|
956
|
-
|
|
957
|
-
var h0 = this.h0, h1 = this.h1, h2 = this.h2, h3 = this.h3, h4 = this.h4, h5 = this.h5,
|
|
958
|
-
h6 = this.h6, h7 = this.h7;
|
|
959
|
-
|
|
960
|
-
var arr = [
|
|
961
|
-
(h0 >>> 24) & 0xFF, (h0 >>> 16) & 0xFF, (h0 >>> 8) & 0xFF, h0 & 0xFF,
|
|
962
|
-
(h1 >>> 24) & 0xFF, (h1 >>> 16) & 0xFF, (h1 >>> 8) & 0xFF, h1 & 0xFF,
|
|
963
|
-
(h2 >>> 24) & 0xFF, (h2 >>> 16) & 0xFF, (h2 >>> 8) & 0xFF, h2 & 0xFF,
|
|
964
|
-
(h3 >>> 24) & 0xFF, (h3 >>> 16) & 0xFF, (h3 >>> 8) & 0xFF, h3 & 0xFF,
|
|
965
|
-
(h4 >>> 24) & 0xFF, (h4 >>> 16) & 0xFF, (h4 >>> 8) & 0xFF, h4 & 0xFF,
|
|
966
|
-
(h5 >>> 24) & 0xFF, (h5 >>> 16) & 0xFF, (h5 >>> 8) & 0xFF, h5 & 0xFF,
|
|
967
|
-
(h6 >>> 24) & 0xFF, (h6 >>> 16) & 0xFF, (h6 >>> 8) & 0xFF, h6 & 0xFF
|
|
968
|
-
];
|
|
969
|
-
if (!this.is224) {
|
|
970
|
-
arr.push((h7 >>> 24) & 0xFF, (h7 >>> 16) & 0xFF, (h7 >>> 8) & 0xFF, h7 & 0xFF);
|
|
971
|
-
}
|
|
972
|
-
return arr;
|
|
973
|
-
};
|
|
974
|
-
|
|
975
|
-
Sha256.prototype.array = Sha256.prototype.digest;
|
|
976
|
-
|
|
977
|
-
Sha256.prototype.arrayBuffer = function () {
|
|
978
|
-
this.finalize();
|
|
979
|
-
|
|
980
|
-
var buffer = new ArrayBuffer(this.is224 ? 28 : 32);
|
|
981
|
-
var dataView = new DataView(buffer);
|
|
982
|
-
dataView.setUint32(0, this.h0);
|
|
983
|
-
dataView.setUint32(4, this.h1);
|
|
984
|
-
dataView.setUint32(8, this.h2);
|
|
985
|
-
dataView.setUint32(12, this.h3);
|
|
986
|
-
dataView.setUint32(16, this.h4);
|
|
987
|
-
dataView.setUint32(20, this.h5);
|
|
988
|
-
dataView.setUint32(24, this.h6);
|
|
989
|
-
if (!this.is224) {
|
|
990
|
-
dataView.setUint32(28, this.h7);
|
|
991
|
-
}
|
|
992
|
-
return buffer;
|
|
993
|
-
};
|
|
994
|
-
|
|
995
|
-
function HmacSha256(key, is224, sharedMemory) {
|
|
996
|
-
var i, type = typeof key;
|
|
997
|
-
if (type === 'string') {
|
|
998
|
-
var bytes = [], length = key.length, index = 0, code;
|
|
999
|
-
for (i = 0; i < length; ++i) {
|
|
1000
|
-
code = key.charCodeAt(i);
|
|
1001
|
-
if (code < 0x80) {
|
|
1002
|
-
bytes[index++] = code;
|
|
1003
|
-
} else if (code < 0x800) {
|
|
1004
|
-
bytes[index++] = (0xc0 | (code >>> 6));
|
|
1005
|
-
bytes[index++] = (0x80 | (code & 0x3f));
|
|
1006
|
-
} else if (code < 0xd800 || code >= 0xe000) {
|
|
1007
|
-
bytes[index++] = (0xe0 | (code >>> 12));
|
|
1008
|
-
bytes[index++] = (0x80 | ((code >>> 6) & 0x3f));
|
|
1009
|
-
bytes[index++] = (0x80 | (code & 0x3f));
|
|
1010
|
-
} else {
|
|
1011
|
-
code = 0x10000 + (((code & 0x3ff) << 10) | (key.charCodeAt(++i) & 0x3ff));
|
|
1012
|
-
bytes[index++] = (0xf0 | (code >>> 18));
|
|
1013
|
-
bytes[index++] = (0x80 | ((code >>> 12) & 0x3f));
|
|
1014
|
-
bytes[index++] = (0x80 | ((code >>> 6) & 0x3f));
|
|
1015
|
-
bytes[index++] = (0x80 | (code & 0x3f));
|
|
1016
|
-
}
|
|
1017
|
-
}
|
|
1018
|
-
key = bytes;
|
|
1019
|
-
} else {
|
|
1020
|
-
if (type === 'object') {
|
|
1021
|
-
if (key === null) {
|
|
1022
|
-
throw new Error(ERROR);
|
|
1023
|
-
} else if (ARRAY_BUFFER && key.constructor === ArrayBuffer) {
|
|
1024
|
-
key = new Uint8Array(key);
|
|
1025
|
-
} else if (!Array.isArray(key)) {
|
|
1026
|
-
if (!ARRAY_BUFFER || !ArrayBuffer.isView(key)) {
|
|
1027
|
-
throw new Error(ERROR);
|
|
1028
|
-
}
|
|
1029
|
-
}
|
|
1030
|
-
} else {
|
|
1031
|
-
throw new Error(ERROR);
|
|
1032
|
-
}
|
|
1033
|
-
}
|
|
1034
|
-
|
|
1035
|
-
if (key.length > 64) {
|
|
1036
|
-
key = (new Sha256(is224, true)).update(key).array();
|
|
1037
|
-
}
|
|
1038
|
-
|
|
1039
|
-
var oKeyPad = [], iKeyPad = [];
|
|
1040
|
-
for (i = 0; i < 64; ++i) {
|
|
1041
|
-
var b = key[i] || 0;
|
|
1042
|
-
oKeyPad[i] = 0x5c ^ b;
|
|
1043
|
-
iKeyPad[i] = 0x36 ^ b;
|
|
1044
|
-
}
|
|
1045
|
-
|
|
1046
|
-
Sha256.call(this, is224, sharedMemory);
|
|
1047
|
-
|
|
1048
|
-
this.update(iKeyPad);
|
|
1049
|
-
this.oKeyPad = oKeyPad;
|
|
1050
|
-
this.inner = true;
|
|
1051
|
-
this.sharedMemory = sharedMemory;
|
|
1052
|
-
}
|
|
1053
|
-
HmacSha256.prototype = new Sha256();
|
|
1054
|
-
|
|
1055
|
-
HmacSha256.prototype.finalize = function () {
|
|
1056
|
-
Sha256.prototype.finalize.call(this);
|
|
1057
|
-
if (this.inner) {
|
|
1058
|
-
this.inner = false;
|
|
1059
|
-
var innerHash = this.array();
|
|
1060
|
-
Sha256.call(this, this.is224, this.sharedMemory);
|
|
1061
|
-
this.update(this.oKeyPad);
|
|
1062
|
-
this.update(innerHash);
|
|
1063
|
-
Sha256.prototype.finalize.call(this);
|
|
1064
|
-
}
|
|
1065
|
-
};
|
|
1066
|
-
|
|
1067
|
-
var exports = createMethod();
|
|
1068
|
-
exports.sha256 = exports;
|
|
1069
|
-
exports.sha224 = createMethod(true);
|
|
1070
|
-
exports.sha256.hmac = createHmacMethod();
|
|
1071
|
-
exports.sha224.hmac = createHmacMethod(true);
|
|
1072
|
-
|
|
1073
|
-
if (COMMON_JS) {
|
|
1074
|
-
module.exports = exports;
|
|
1075
|
-
} else {
|
|
1076
|
-
root.sha256 = exports.sha256;
|
|
1077
|
-
root.sha224 = exports.sha224;
|
|
1078
|
-
}
|
|
1079
|
-
})();
|
|
1080
|
-
}(sha256));
|
|
1081
|
-
|
|
1082
|
-
const isBrowser$1 = typeof window !== 'undefined';
|
|
1083
|
-
const isServer$1 = !isBrowser$1;
|
|
554
|
+
const isBrowser$2 = typeof window !== 'undefined';
|
|
555
|
+
const isServer$2 = !isBrowser$2;
|
|
1084
556
|
const standardFacebookEvents = ['AddPaymentInfo', 'AddToCart', 'AddToWishlist', 'CompleteRegistration', 'Contact', 'CustomizeProduct', 'Donate', 'FindLocation', 'InitiateCheckout', 'Lead', 'Purchase', 'Schedule', 'Search', 'StartTrial', 'SubmitApplication', 'Subscribe', 'ViewContent', 'PageView'];
|
|
1085
557
|
/**
|
|
1086
558
|
* Create a Facebook Pixel integration instance
|
|
@@ -1091,7 +563,7 @@ function createFacebookPixelIntegration(config) {
|
|
|
1091
563
|
name: 'facebook-pixel',
|
|
1092
564
|
environments: ['client'],
|
|
1093
565
|
init: () => __awaiter(this, void 0, void 0, function* () {
|
|
1094
|
-
if (isServer$
|
|
566
|
+
if (isServer$2) {
|
|
1095
567
|
// On server, Facebook Pixel is a no-op but doesn't throw
|
|
1096
568
|
// This allows the integration to be registered but remain inactive
|
|
1097
569
|
return;
|
|
@@ -1170,9 +642,13 @@ function createFacebookPixelIntegration(config) {
|
|
|
1170
642
|
const amValues = coerceMetaConversionsAmValues(Object.assign(Object.assign({}, properties || {}), userId ? {
|
|
1171
643
|
external_id: userId
|
|
1172
644
|
} : {}));
|
|
645
|
+
// Advanced Matching
|
|
646
|
+
// Add event to identify user and hash email field
|
|
647
|
+
// FB pixel handles hashing automatically
|
|
648
|
+
// https://developers.facebook.com/docs/meta-pixel/advanced/advanced-matching/
|
|
1173
649
|
const am = {};
|
|
1174
650
|
if (amValues.external_id) am['external_id'] = amValues.external_id;
|
|
1175
|
-
if (amValues.em) am['em'] = sha256
|
|
651
|
+
if (amValues.em) am['em'] = sha256(amValues.em);
|
|
1176
652
|
if (amValues.fn) am['fn'] = amValues.fn;
|
|
1177
653
|
if (amValues.ln) am['ln'] = amValues.ln;
|
|
1178
654
|
if (amValues.ph) am['ph'] = amValues.ph;
|
|
@@ -1198,6 +674,18 @@ function getFacebookEventName(eventName, eventMapping) {
|
|
|
1198
674
|
if (!eventMapping) return eventName;
|
|
1199
675
|
return eventMapping[eventName] || eventName;
|
|
1200
676
|
}
|
|
677
|
+
/**
|
|
678
|
+
* Get Advanced Matching values from properties
|
|
679
|
+
*
|
|
680
|
+
* Documentation for Pixel
|
|
681
|
+
* https://developers.facebook.com/docs/meta-pixel/advanced/advanced-matching/
|
|
682
|
+
*
|
|
683
|
+
* Documentation for Conversions API
|
|
684
|
+
* https://developers.secure.facebook.com/docs/marketing-api/conversions-api/parameters/customer-information-parameters
|
|
685
|
+
*
|
|
686
|
+
* @param properties
|
|
687
|
+
* @returns
|
|
688
|
+
*/
|
|
1201
689
|
function coerceMetaConversionsAmValues(properties) {
|
|
1202
690
|
const coerce = [{
|
|
1203
691
|
key: 'em',
|
|
@@ -1305,6 +793,214 @@ function coerceMetaConversionsAmValues(properties) {
|
|
|
1305
793
|
}
|
|
1306
794
|
}];
|
|
1307
795
|
const result = {};
|
|
796
|
+
for (const {
|
|
797
|
+
key,
|
|
798
|
+
coerceFrom,
|
|
799
|
+
transform
|
|
800
|
+
} of coerce) {
|
|
801
|
+
const foundValue = findFirstProperty$1(properties, coerceFrom);
|
|
802
|
+
if (foundValue !== null && transform) {
|
|
803
|
+
const transformedValue = transform(foundValue);
|
|
804
|
+
if (transformedValue) {
|
|
805
|
+
result[key] = transformedValue;
|
|
806
|
+
}
|
|
807
|
+
} else if (foundValue !== null && typeof foundValue === 'string') {
|
|
808
|
+
result[key] = foundValue;
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
return result;
|
|
812
|
+
}
|
|
813
|
+
function findFirstProperty$1(properties, keys) {
|
|
814
|
+
for (const key of keys) {
|
|
815
|
+
if (properties[key] !== undefined) {
|
|
816
|
+
return properties[key];
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
return null;
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
/**
|
|
823
|
+
* TikTok Pixel Integration
|
|
824
|
+
*
|
|
825
|
+
* This integration provides TikTok Pixel tracking capabilities including:
|
|
826
|
+
* - Event tracking for standard and custom events
|
|
827
|
+
* - Advanced matching with hashed user identification data
|
|
828
|
+
* - Automatic script loading and initialization
|
|
829
|
+
*
|
|
830
|
+
* Key Resources:
|
|
831
|
+
* - Advanced Matching: https://business-api.tiktok.com/portal/docs?rid=5ipocbxyw8v&id=1739585700402178
|
|
832
|
+
* - Standard Events: https://business-api.tiktok.com/portal/docs?id=1771101186666498
|
|
833
|
+
*/
|
|
834
|
+
const isBrowser$1 = typeof window !== 'undefined';
|
|
835
|
+
const isServer$1 = !isBrowser$1;
|
|
836
|
+
/**
|
|
837
|
+
* Standard TikTok events supported by the pixel
|
|
838
|
+
*
|
|
839
|
+
* Note: This list reflects TikTok's official standard events. Events like 'CompletePayment'
|
|
840
|
+
* are not standard events and should be tracked as custom events if needed.
|
|
841
|
+
*
|
|
842
|
+
* Documentation: https://business-api.tiktok.com/portal/docs?id=1771101186666498
|
|
843
|
+
*/
|
|
844
|
+
const standardTikTokEvents = ['AddPaymentInfo', 'AddToCart', 'AddToWishlist', 'ApplicationApproval', 'CompleteRegistration', 'Contact', 'CustomizeProduct', 'Download', 'FindLocation', 'InitiateCheckout', 'Lead', 'Purchase', 'Schedule', 'Search', 'StartTrial', 'SubmitApplication', 'Subscribe', 'ViewContent', 'PageView'];
|
|
845
|
+
/**
|
|
846
|
+
* Create a TikTok Pixel integration instance
|
|
847
|
+
*/
|
|
848
|
+
function createTikTokPixelIntegration(config) {
|
|
849
|
+
let isPixelReady = false;
|
|
850
|
+
return {
|
|
851
|
+
name: 'tiktok-pixel',
|
|
852
|
+
environments: ['client'],
|
|
853
|
+
init: () => __awaiter(this, void 0, void 0, function* () {
|
|
854
|
+
if (isServer$1) {
|
|
855
|
+
// On server, TikTok Pixel is a no-op but doesn't throw
|
|
856
|
+
// This allows the integration to be registered but remain inactive
|
|
857
|
+
return;
|
|
858
|
+
}
|
|
859
|
+
// Check if TikTok Pixel is already loaded
|
|
860
|
+
if (window.ttq) {
|
|
861
|
+
console.warn('TikTok Pixel is already initialized');
|
|
862
|
+
isPixelReady = true;
|
|
863
|
+
return;
|
|
864
|
+
}
|
|
865
|
+
// Initialize TikTok Pixel
|
|
866
|
+
return new Promise((resolve, reject) => {
|
|
867
|
+
try {
|
|
868
|
+
(function (w, d, t) {
|
|
869
|
+
w.TiktokAnalyticsObject = t;
|
|
870
|
+
const ttq = w[t] = w[t] || [];
|
|
871
|
+
ttq.methods = ['page', 'track', 'identify', 'instances', 'debug', 'on', 'off', 'once', 'ready', 'alias', 'group', 'enableCookie', 'disableCookie', 'holdConsent', 'revokeConsent', 'grantConsent'];
|
|
872
|
+
ttq.setAndDefer = function (t, e) {
|
|
873
|
+
t[e] = function () {
|
|
874
|
+
t.push([e].concat(Array.prototype.slice.call(arguments, 0)));
|
|
875
|
+
};
|
|
876
|
+
};
|
|
877
|
+
for (let i = 0; i < ttq.methods.length; i++) ttq.setAndDefer(ttq, ttq.methods[i]);
|
|
878
|
+
ttq.instance = function (t) {
|
|
879
|
+
const e = ttq._i[t] || [];
|
|
880
|
+
for (let n = 0; n < ttq.methods.length; n++) ttq.setAndDefer(e, ttq.methods[n]);
|
|
881
|
+
return e;
|
|
882
|
+
};
|
|
883
|
+
ttq.load = function (e, n) {
|
|
884
|
+
const r = 'https://analytics.tiktok.com/i18n/pixel/events.js';
|
|
885
|
+
const o = n && n.partner;
|
|
886
|
+
ttq._i = ttq._i || {};
|
|
887
|
+
ttq._i[e] = [];
|
|
888
|
+
ttq._i[e]._u = r;
|
|
889
|
+
ttq._t = ttq._t || {};
|
|
890
|
+
ttq._t[e] = +new Date();
|
|
891
|
+
ttq._o = ttq._o || {};
|
|
892
|
+
ttq._o[e] = n || {};
|
|
893
|
+
const script = document.createElement('script');
|
|
894
|
+
script.type = 'text/javascript';
|
|
895
|
+
script.async = true;
|
|
896
|
+
script.src = r + '?sdkid=' + e + '&lib=' + t;
|
|
897
|
+
// Add load event listener
|
|
898
|
+
script.onload = () => {
|
|
899
|
+
isPixelReady = true;
|
|
900
|
+
resolve();
|
|
901
|
+
};
|
|
902
|
+
script.onerror = () => {
|
|
903
|
+
reject(new Error('Failed to load TikTok Pixel script'));
|
|
904
|
+
};
|
|
905
|
+
const firstScript = document.getElementsByTagName('script')[0];
|
|
906
|
+
firstScript.parentNode.insertBefore(script, firstScript);
|
|
907
|
+
};
|
|
908
|
+
// Load the pixel with the provided ID
|
|
909
|
+
ttq.load(config.pixelId, config.testMode ? {
|
|
910
|
+
test_mode: true
|
|
911
|
+
} : undefined);
|
|
912
|
+
ttq.page();
|
|
913
|
+
// If script loads synchronously, mark as ready
|
|
914
|
+
if (window.ttq && typeof window.ttq === 'function') {
|
|
915
|
+
isPixelReady = true;
|
|
916
|
+
resolve();
|
|
917
|
+
}
|
|
918
|
+
})(window, document, 'ttq');
|
|
919
|
+
} catch (error) {
|
|
920
|
+
reject(error);
|
|
921
|
+
}
|
|
922
|
+
});
|
|
923
|
+
}),
|
|
924
|
+
track: (eventName, properties, context) => {
|
|
925
|
+
if (!isPixelReady || !window.ttq) return;
|
|
926
|
+
const ttEventName = getTikTokEventName(eventName, config.eventMapping);
|
|
927
|
+
// Handle PageView separately as it uses ttq.page()
|
|
928
|
+
if (ttEventName === 'PageView') {
|
|
929
|
+
window.ttq.page();
|
|
930
|
+
return;
|
|
931
|
+
}
|
|
932
|
+
// Map parameters based on specific event requirements
|
|
933
|
+
const ttParams = mapTikTokEventParameters(ttEventName, properties);
|
|
934
|
+
if (ttParams && Object.keys(ttParams).length > 0) {
|
|
935
|
+
window.ttq.track(ttEventName, ttParams);
|
|
936
|
+
} else {
|
|
937
|
+
window.ttq.track(ttEventName);
|
|
938
|
+
}
|
|
939
|
+
},
|
|
940
|
+
identify: (userId, properties, context) => {
|
|
941
|
+
try {
|
|
942
|
+
if (typeof window !== 'undefined' && window.ttq) {
|
|
943
|
+
const identifyData = coerceTikTokIdentifyValues(Object.assign(Object.assign({}, properties || {}), userId ? {
|
|
944
|
+
external_id: userId
|
|
945
|
+
} : {}));
|
|
946
|
+
if (Object.keys(identifyData).length > 0) {
|
|
947
|
+
window.ttq.identify(identifyData);
|
|
948
|
+
}
|
|
949
|
+
}
|
|
950
|
+
} catch (error) {
|
|
951
|
+
console.error('Error identifying user in TikTok Pixel:', error);
|
|
952
|
+
}
|
|
953
|
+
}
|
|
954
|
+
};
|
|
955
|
+
}
|
|
956
|
+
function getTikTokEventName(eventName, eventMapping) {
|
|
957
|
+
// Convert default saasco Page View event by default
|
|
958
|
+
if (eventName === 'Page View') return 'PageView';
|
|
959
|
+
if (!eventMapping) return eventName;
|
|
960
|
+
return eventMapping[eventName] || eventName;
|
|
961
|
+
}
|
|
962
|
+
/**
|
|
963
|
+
* Get identification values from properties for TikTok Pixel
|
|
964
|
+
*
|
|
965
|
+
* Advanced Matching Documentation:
|
|
966
|
+
* https://business-api.tiktok.com/portal/docs?rid=5ipocbxyw8v&id=1739585700402178
|
|
967
|
+
*
|
|
968
|
+
* Standard Events Documentation:
|
|
969
|
+
* https://business-api.tiktok.com/portal/docs?id=1771101186666498
|
|
970
|
+
*
|
|
971
|
+
* @param properties
|
|
972
|
+
* @returns
|
|
973
|
+
*/
|
|
974
|
+
function coerceTikTokIdentifyValues(properties) {
|
|
975
|
+
const coerce = [{
|
|
976
|
+
key: 'email',
|
|
977
|
+
coerceFrom: ['email', 'user_email', 'userEmail', 'email_address', 'emailAddress', 'e_mail', 'E_Mail', 'mail', 'Mail', 'contact_email', 'contactEmail', 'primary_email', 'primaryEmail'],
|
|
978
|
+
transform: value => {
|
|
979
|
+
if (typeof value !== 'string') return undefined;
|
|
980
|
+
const normalized = value.trim().toLowerCase();
|
|
981
|
+
// TikTok requires hashed email
|
|
982
|
+
return normalized ? sha256(normalized) : undefined;
|
|
983
|
+
}
|
|
984
|
+
}, {
|
|
985
|
+
key: 'phone_number',
|
|
986
|
+
coerceFrom: ['phone', 'phone_number', 'phoneNumber', 'mobile', 'mobile_number', 'mobileNumber', 'contact_number', 'contactNumber', 'tel', 'telephone'],
|
|
987
|
+
transform: value => {
|
|
988
|
+
if (typeof value !== 'string' && typeof value !== 'number') return undefined;
|
|
989
|
+
const phoneStr = String(value).replace(/\D/g, '');
|
|
990
|
+
// TikTok requires hashed phone number
|
|
991
|
+
return phoneStr ? sha256(phoneStr) : undefined;
|
|
992
|
+
}
|
|
993
|
+
}, {
|
|
994
|
+
key: 'external_id',
|
|
995
|
+
coerceFrom: ['external_id', 'externalId', 'user_id', 'userId', 'id', 'distinctId', 'distinct_id', 'customer_id', 'customerId', 'member_id', 'memberId'],
|
|
996
|
+
transform: value => {
|
|
997
|
+
if (value == null) return undefined;
|
|
998
|
+
const stringValue = String(value);
|
|
999
|
+
// TikTok requires hashed external_id
|
|
1000
|
+
return stringValue ? sha256(stringValue) : undefined;
|
|
1001
|
+
}
|
|
1002
|
+
}];
|
|
1003
|
+
const result = {};
|
|
1308
1004
|
for (const {
|
|
1309
1005
|
key,
|
|
1310
1006
|
coerceFrom,
|
|
@@ -1330,6 +1026,63 @@ function findFirstProperty(properties, keys) {
|
|
|
1330
1026
|
}
|
|
1331
1027
|
return null;
|
|
1332
1028
|
}
|
|
1029
|
+
/**
|
|
1030
|
+
* Maps event properties to TikTok-specific parameters based on event type
|
|
1031
|
+
*
|
|
1032
|
+
* Parameter Documentation: https://ads.tiktok.com/help/article/about-parameters
|
|
1033
|
+
* Standard Events: https://business-api.tiktok.com/portal/docs?id=1771101186666498
|
|
1034
|
+
*/
|
|
1035
|
+
function mapTikTokEventParameters(eventName, properties) {
|
|
1036
|
+
if (!properties) return null;
|
|
1037
|
+
const params = {};
|
|
1038
|
+
// Helper to safely add parameters, skipping objects/null/undefined
|
|
1039
|
+
const addParam = (key, value) => {
|
|
1040
|
+
if (value != null && typeof value !== 'object') {
|
|
1041
|
+
params[key] = value;
|
|
1042
|
+
}
|
|
1043
|
+
};
|
|
1044
|
+
switch (eventName) {
|
|
1045
|
+
case 'AddToCart':
|
|
1046
|
+
case 'Purchase':
|
|
1047
|
+
case 'ViewContent':
|
|
1048
|
+
addParam('content_type', properties['content_type']);
|
|
1049
|
+
addParam('content_ids', properties['content_ids']);
|
|
1050
|
+
addParam('quantity', properties['quantity']);
|
|
1051
|
+
addParam('description', properties['description']);
|
|
1052
|
+
addParam('currency', properties['currency']);
|
|
1053
|
+
addParam('value', properties['value']);
|
|
1054
|
+
addParam('content_name', properties['content_name']);
|
|
1055
|
+
addParam('content_category', properties['content_category']);
|
|
1056
|
+
break;
|
|
1057
|
+
case 'StartTrial':
|
|
1058
|
+
addParam('content_ids', properties['content_ids']);
|
|
1059
|
+
addParam('currency', properties['currency']);
|
|
1060
|
+
addParam('value', properties['value']);
|
|
1061
|
+
break;
|
|
1062
|
+
case 'Search':
|
|
1063
|
+
const searchString = properties['search_string'] || properties['query'] || properties['search_query'];
|
|
1064
|
+
addParam('search_string', searchString);
|
|
1065
|
+
break;
|
|
1066
|
+
case 'InitiateCheckout':
|
|
1067
|
+
case 'AddPaymentInfo':
|
|
1068
|
+
addParam('value', properties['value']);
|
|
1069
|
+
addParam('currency', properties['currency']);
|
|
1070
|
+
addParam('content_ids', properties['content_ids']);
|
|
1071
|
+
addParam('quantity', properties['quantity']);
|
|
1072
|
+
break;
|
|
1073
|
+
case 'CompleteRegistration':
|
|
1074
|
+
case 'Subscribe':
|
|
1075
|
+
addParam('value', properties['value']);
|
|
1076
|
+
addParam('currency', properties['currency']);
|
|
1077
|
+
break;
|
|
1078
|
+
default:
|
|
1079
|
+
// Pass through common parameters for any other events
|
|
1080
|
+
addParam('value', properties['value']);
|
|
1081
|
+
addParam('currency', properties['currency']);
|
|
1082
|
+
break;
|
|
1083
|
+
}
|
|
1084
|
+
return Object.keys(params).length > 0 ? params : null;
|
|
1085
|
+
}
|
|
1333
1086
|
|
|
1334
1087
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
1335
1088
|
class AnalyticsLogger {
|
|
@@ -1858,6 +1611,10 @@ class Saasco {
|
|
|
1858
1611
|
this.logger.log('Registering Facebook Pixel integration with ID:', integrationConfig.config.pixelId);
|
|
1859
1612
|
const fbIntegration = createFacebookPixelIntegration(integrationConfig.config);
|
|
1860
1613
|
yield this.integrationManager.registerIntegration(fbIntegration);
|
|
1614
|
+
} else if (integrationConfig.type === 'tiktok-pixel') {
|
|
1615
|
+
this.logger.log('Registering TikTok Pixel integration with ID:', integrationConfig.config.pixelId);
|
|
1616
|
+
const tiktokIntegration = createTikTokPixelIntegration(integrationConfig.config);
|
|
1617
|
+
yield this.integrationManager.registerIntegration(tiktokIntegration);
|
|
1861
1618
|
}
|
|
1862
1619
|
} catch (error) {
|
|
1863
1620
|
this.logger.log(`Failed to register ${integrationConfig.type} integration:`, error);
|
|
@@ -2118,4 +1875,4 @@ const browserContextSchema = z.object({
|
|
|
2118
1875
|
$utmAdId: z.string().nullable()
|
|
2119
1876
|
});
|
|
2120
1877
|
|
|
2121
|
-
export { IntegrationManager, Logger, Saasco, browserContextSchema, createFacebookPixelIntegration, getBrowserContext, standardFacebookEvents, timezones };
|
|
1878
|
+
export { IntegrationManager, Logger, Saasco, browserContextSchema, createFacebookPixelIntegration, createTikTokPixelIntegration, getBrowserContext, standardFacebookEvents, standardTikTokEvents, timezones };
|