31
31
## Tag Parameters
32
32
33
33
- ` audio_content ` ;
34
+ - ` audio_content_type ` ;
34
35
- ` audio_current_time ` ;
35
36
- ` audio_duration ` ;
36
37
- ` audio_percent ` ;
@@ -97,34 +98,34 @@ spotifyPlayer.contentWindow.postMessage({
97
98
98
99
``` html
99
100
<script >
100
- // - The operation below is needed to ensure the list of
101
+ // - The operation below is needed to assure the list of
101
102
// percentages to be detected as progress events follow
102
103
// the correct format.
103
- function truncateRemoveInvalidValuesDeduplicateSort (arr ) {
104
- var truncatedList = arr .map (function (element ) {
105
- return Math .trunc (element);
106
- }).filter (function (element ) {
107
- return element > 0 && element < 100 ;
108
- });
109
- var uniqueValuesObject = {};
110
- for (var i = 0 ; i < truncatedList .length ; i++ ) {
111
- uniqueValuesObject[truncatedList[i]] = true ;
104
+ var spotifyPercentagesToBeDetected = (
105
+ function (arr ) {
106
+ var truncatedList = arr .map (function (element ) {
107
+ return Math .trunc (element);
108
+ }).filter (function (element ) {
109
+ return element > 0 && element < 100 ;
110
+ });
111
+ var uniqueValuesObject = {};
112
+ for (var i = 0 ; i < truncatedList .length ; i++ ) {
113
+ uniqueValuesObject[truncatedList[i]] = true ;
114
+ }
115
+ var uniqueList = Object .keys (uniqueValuesObject).map (function (key ) {
116
+ return parseInt (key, 10 );
117
+ });
118
+ uniqueList .sort (function (a , b ) {
119
+ return a - b;
120
+ });
121
+ return uniqueList;
112
122
}
113
- var uniqueList = Object .keys (uniqueValuesObject).map (function (key ) {
114
- return parseInt (key, 10 );
115
- });
116
- uniqueList .sort (function (a , b ) {
117
- return a - b;
118
- });
119
- return uniqueList;
120
- }
121
-
122
- // - Edit the list below to setup progress events' percentage values:
123
- // (List with unique integer values ranging from 1 to 99, sorted in ascending order)
124
- var spotifyPercentagesToBeDetected = truncateRemoveInvalidValuesDeduplicateSort (
123
+ (
124
+ // - Edit the list below to setup progress events' percentage values:
125
125
[99 , 20 , 10.5 , 60 , 100 , 40.05 , 80 , 90 , 30 , 50 , 70 , 0 , 99.3 ]
126
+ // (Expected: list with unique integer values ranging from 1 to 99, sorted in ascending order)
126
127
);
127
- // List is certainly [10, 20, 30, 40, 50, 60, 70, 80, 90, 99] after the cleansing .
128
+ // List is certainly [10, 20, 30, 40, 50, 60, 70, 80, 90, 99] after being processed .
128
129
129
130
// - Check if a calculated percentage value should or not be detected.
130
131
function shouldPercentageBeDetected (percent , detectionList ) {
@@ -147,11 +148,19 @@ window.addEventListener('message', function(event) {
147
148
var audioCurrentTime = (event .data .payload .position / 1000 ) || 0 ;
148
149
var audioDuration = (event .data .payload .duration / 1000 ) || 0 ;
149
150
var spotifyURI = event .data .payload .playingURI ;
151
+ var audioContentType = (
152
+ function (uri ) {
153
+ var reSpotifyUri = / spotify:([^ :] + ):[^ :] + / i ;
154
+ if (reSpotifyUri .test (uri))
155
+ return reSpotifyUri .exec (uri)[1 ];
156
+ return ' ' ;
157
+ })(spotifyURI);
150
158
var spotifyEvent = {
151
159
event : ' spotifyEvent' ,
152
160
audioPercent: audioPercent,
153
161
audioCurrentTime: audioCurrentTime,
154
162
audioDuration: audioDuration,
163
+ audioContentType: audioContentType,
155
164
spotifyURI: spotifyURI
156
165
}
157
166
// - Restart Playback Control Variables in case URI ou Duration has
@@ -219,7 +228,7 @@ window.addEventListener('message', function(event) {
219
228
` ` ` json
220
229
{
221
230
" exportFormatVersion" : 2 ,
222
- "exportTime" : " 2025-05-11 04:23:21 " ,
231
+ " exportTime" : " 2025-05-13 02:28:26 " ,
223
232
" containerVersion" : {
224
233
" path" : " accounts/6054360526/containers/218106977/versions/0" ,
225
234
" accountId" : " 6054360526" ,
@@ -367,6 +376,21 @@ window.addEventListener('message', function(event) {
367
376
" value" : " {{DLV - audioCurrentTime}}"
368
377
}
369
378
]
379
+ },
380
+ {
381
+ " type" : " MAP" ,
382
+ " map" : [
383
+ {
384
+ " type" : " TEMPLATE" ,
385
+ " key" : " parameter" ,
386
+ " value" : " audio_content_type"
387
+ },
388
+ {
389
+ " type" : " TEMPLATE" ,
390
+ " key" : " parameterValue" ,
391
+ " value" : " {{DLV - audioContentType}}"
392
+ }
393
+ ]
370
394
}
371
395
]
372
396
},
@@ -381,7 +405,7 @@ window.addEventListener('message', function(event) {
381
405
" value" : " {{GA4 - Property ID}}"
382
406
}
383
407
],
384
- "fingerprint" : " 1746796666011 " ,
408
+ " fingerprint" : " 1747101871290 " ,
385
409
" firingTriggerId" : [
386
410
" 40"
387
411
],
@@ -404,15 +428,15 @@ window.addEventListener('message', function(event) {
404
428
{
405
429
" type" : " TEMPLATE" ,
406
430
" key" : " html" ,
407
- "value": "<script>\n// - The operation below is needed to assure the list of\n// percentages to be detected as progress events follow\n// the correct format.\nfunction truncateRemoveInvalidValuesDeduplicateSort(arr) {\n var truncatedList = arr.map(function(element) {\n return Math.trunc(element);\n }).filter(function(element) {\n return element > 0 && element < 100;\n });\n var uniqueValuesObject = {};\n for (var i = 0; i < truncatedList.length; i++) {\n uniqueValuesObject[truncatedList[i]] = true;\n }\n var uniqueList = Object.keys(uniqueValuesObject).map(function(key) {\n return parseInt(key, 10);\n });\n uniqueList.sort(function(a, b) {\n return a - b;\n });\n return uniqueList;\n}\n\n// - Edit the list below to setup progress events' percentage values:\n// (List with unique integer values ranging from 1 to 99, sorted in ascending order)\nvar spotifyPercentagesToBeDetected = truncateRemoveInvalidValuesDeduplicateSort(\n [99, 20, 10.5, 60, 100, 40.05, 80, 90, 30, 50, 70, 0, 99.3]\n);\n// List is certainly [10, 20, 30, 40, 50, 60, 70, 80, 90, 99] after the cleansing.\n\n// - Check if a calculated percentage value should or not be detected.\nfunction shouldPercentageBeDetected(percent, detectionList) {\n for (var i = 0; i < detectionList.length; i++) {\n if (percent >= detectionList[i] && !(detectionList[i+1] && detectionList[i+1] <= percent)) {\n return { check: true, value: detectionList[i] };\n }\n }\n return { check: false, value: undefined };\n}\n\nvar spotifyWasPaused = false;\nvar spotifyAudioCompleted = false;\nvar spotifyRegisteredProgress = [];\nvar spotifyLastDuration = 0.0;\nvar spotifyLastURI = '';\nwindow.addEventListener('message', function(event) {\n if (event.origin === 'https://open.spotify.com') {\n var audioPercent = Math.trunc((event.data.payload.position / event.data.payload.duration) * 100) || 0;\n var audioCurrentTime = (event.data.payload.position / 1000) || 0;\n var audioDuration = (event.data.payload.duration / 1000) || 0;\n var spotifyURI = event.data.payload.playingURI;\n var spotifyEvent = {\n event: 'spotifyEvent',\n audioPercent: audioPercent,\n audioCurrentTime: audioCurrentTime,\n audioDuration: audioDuration,\n spotifyURI: spotifyURI\n }\n // - Restart Playback Control Variables in case URI ou Duration has\n // changed (track change detection within playlist, album or artist).\n if ((spotifyURI && spotifyURI !== spotifyLastURI) || (spotifyURI && spotifyURI === spotifyLastURI && spotifyLastDuration !== audioDuration && spotifyLastDuration && audioDuration && Math.round(spotifyLastDuration) !== Math.round(audioDuration))) {\n spotifyAudioCompleted = false;\n spotifyWasPaused = false;\n spotifyRegisteredProgress = [];\n }\n // 1. Progress Events\n if (spotifyURI && shouldPercentageBeDetected(audioPercent, spotifyPercentagesToBeDetected).check) {\n if (!spotifyRegisteredProgress.includes(shouldPercentageBeDetected(audioPercent, spotifyPercentagesToBeDetected).value)) {\n spotifyRegisteredProgress.push(shouldPercentageBeDetected(audioPercent, spotifyPercentagesToBeDetected).value);\n spotifyEvent.audioStatus = 'progress';\n spotifyEvent.audioPercent = shouldPercentageBeDetected(audioPercent, spotifyPercentagesToBeDetected).value;\n dataLayer.push(spotifyEvent);\n spotifyLastURI = spotifyURI;\n if (audioDuration) spotifyLastDuration = audioDuration;\n }\n }\n // 2. Playback updates\n // 2.1. Playback Start\n if (spotifyURI && event.data.type === 'playback_started') {\n spotifyEvent.audioStatus = 'playback_started';\n dataLayer.push(spotifyEvent);\n spotifyLastURI = spotifyURI;\n // 2.2. Playback Paused\n } else if (spotifyURI && event.data.type === 'playback_update' && event.data.payload.isPaused && audioCurrentTime && !spotifyWasPaused) {\n spotifyEvent.audioStatus = 'playback_paused';\n dataLayer.push(spotifyEvent);\n spotifyLastURI = spotifyURI;\n if (audioDuration) spotifyLastDuration = audioDuration;\n spotifyWasPaused = true;\n // 2.3. Playback Resumed\n } else if (spotifyURI && event.data.type === 'playback_update' && !event.data.payload.isPaused && spotifyWasPaused && event.data.payload.position) {\n spotifyEvent.audioStatus = 'playback_resumed';\n dataLayer.push(spotifyEvent);\n spotifyLastURI = spotifyURI;\n if (audioDuration) spotifyLastDuration = audioDuration;\n spotifyWasPaused = false;\n // 2.4. Complete\n } else if (spotifyURI && event.data.type === 'playback_update' && audioDuration === audioCurrentTime && !spotifyAudioCompleted) {\n spotifyEvent.audioStatus = 'complete';\n spotifyEvent.audioPercent = 100;\n dataLayer.push(spotifyEvent);\n spotifyLastURI = spotifyURI;\n if (audioDuration) spotifyLastDuration = audioDuration;\n spotifyAudioCompleted = true;\n }\n }\n}, false);\n</script>"
431
+ "value": "<script>\n// - The operation below is needed to assure the list of\n// percentages to be detected as progress events follow\n// the correct format.\nvar spotifyPercentagesToBeDetected = (\n function(arr) {\n var truncatedList = arr.map(function(element) {\n return Math.trunc(element);\n }).filter(function(element) {\n return element > 0 && element < 100;\n });\n var uniqueValuesObject = {};\n for (var i = 0; i < truncatedList.length; i++) {\n uniqueValuesObject[truncatedList[i]] = true;\n }\n var uniqueList = Object.keys(uniqueValuesObject).map(function(key) {\n return parseInt(key, 10);\n });\n uniqueList.sort(function(a, b) {\n return a - b;\n });\n return uniqueList;\n }\n)(\n // - Edit the list below to setup progress events' percentage values:\n [99, 20, 10.5, 60, 100, 40.05, 80, 90, 30, 50, 70, 0, 99.3]\n // (Expected: list with unique integer values ranging from 1 to 99, sorted in ascending order)\n);\n// List is certainly [10, 20, 30, 40, 50, 60, 70, 80, 90, 99] after being processed.\n\n// - Check if a calculated percentage value should or not be detected.\nfunction shouldPercentageBeDetected(percent, detectionList) {\n for (var i = 0; i < detectionList.length; i++) {\n if (percent >= detectionList[i] && !(detectionList[i+1] && detectionList[i+1] <= percent)) {\n return { check: true, value: detectionList[i] };\n }\n }\n return { check: false, value: undefined };\n}\n\nvar spotifyWasPaused = false;\nvar spotifyAudioCompleted = false;\nvar spotifyRegisteredProgress = [];\nvar spotifyLastDuration = 0.0;\nvar spotifyLastURI = '';\nwindow.addEventListener('message', function(event) {\n if (event.origin === 'https://open.spotify.com') {\n var audioPercent = Math.trunc((event.data.payload.position / event.data.payload.duration) * 100) || 0;\n var audioCurrentTime = (event.data.payload.position / 1000) || 0;\n var audioDuration = (event.data.payload.duration / 1000) || 0;\n var spotifyURI = event.data.payload.playingURI;\n var audioContentType = (\n function(uri) { \n var reSpotifyUri = /spotify:([^:]+):[^:]+/i;\n if (reSpotifyUri.test(uri))\n return reSpotifyUri.exec(uri)[1];\n return '';\n })(spotifyURI);\n var spotifyEvent = {\n event: 'spotifyEvent',\n audioPercent: audioPercent,\n audioCurrentTime: audioCurrentTime,\n audioDuration: audioDuration,\n audioContentType: audioContentType,\n spotifyURI: spotifyURI\n }\n // - Restart Playback Control Variables in case URI ou Duration has\n // changed (track change detection within playlist, album or artist).\n if ((spotifyURI && spotifyURI !== spotifyLastURI) || (spotifyURI && spotifyURI === spotifyLastURI && spotifyLastDuration !== audioDuration && spotifyLastDuration && audioDuration && Math.round(spotifyLastDuration) !== Math.round(audioDuration))) {\n spotifyAudioCompleted = false;\n spotifyWasPaused = false;\n spotifyRegisteredProgress = [];\n }\n // 1. Progress Events\n if (spotifyURI && shouldPercentageBeDetected(audioPercent, spotifyPercentagesToBeDetected).check) {\n if (!spotifyRegisteredProgress.includes(shouldPercentageBeDetected(audioPercent, spotifyPercentagesToBeDetected).value)) {\n spotifyRegisteredProgress.push(shouldPercentageBeDetected(audioPercent, spotifyPercentagesToBeDetected).value);\n spotifyEvent.audioStatus = 'progress';\n spotifyEvent.audioPercent = shouldPercentageBeDetected(audioPercent, spotifyPercentagesToBeDetected).value;\n dataLayer.push(spotifyEvent);\n spotifyLastURI = spotifyURI;\n if (audioDuration) spotifyLastDuration = audioDuration;\n }\n }\n // 2. Playback updates\n // 2.1. Playback Start\n if (spotifyURI && event.data.type === 'playback_started') {\n spotifyEvent.audioStatus = 'playback_started';\n dataLayer.push(spotifyEvent);\n spotifyLastURI = spotifyURI;\n // 2.2. Playback Paused\n } else if (spotifyURI && event.data.type === 'playback_update' && event.data.payload.isPaused && audioCurrentTime && !spotifyWasPaused) {\n spotifyEvent.audioStatus = 'playback_paused';\n dataLayer.push(spotifyEvent);\n spotifyLastURI = spotifyURI;\n if (audioDuration) spotifyLastDuration = audioDuration;\n spotifyWasPaused = true;\n // 2.3. Playback Resumed\n } else if (spotifyURI && event.data.type === 'playback_update' && !event.data.payload.isPaused && spotifyWasPaused && event.data.payload.position) {\n spotifyEvent.audioStatus = 'playback_resumed';\n dataLayer.push(spotifyEvent);\n spotifyLastURI = spotifyURI;\n if (audioDuration) spotifyLastDuration = audioDuration;\n spotifyWasPaused = false;\n // 2.4. Complete\n } else if (spotifyURI && event.data.type === 'playback_update' && audioDuration === audioCurrentTime && !spotifyAudioCompleted) {\n spotifyEvent.audioStatus = 'complete';\n spotifyEvent.audioPercent = 100;\n dataLayer.push(spotifyEvent);\n spotifyLastURI = spotifyURI;\n if (audioDuration) spotifyLastDuration = audioDuration;\n spotifyAudioCompleted = true;\n }\n }\n}, false);\n</script>"
408
432
},
409
433
{
410
434
" type" : " BOOLEAN" ,
411
435
" key" : " supportDocumentWrite" ,
412
436
" value" : " false"
413
437
}
414
438
],
415
- "fingerprint" : " 1746892858395 " ,
439
+ " fingerprint" : " 1747102916182 " ,
416
440
" firingTriggerId" : [
417
441
" 2147479553"
418
442
],
@@ -589,6 +613,33 @@ window.addEventListener('message', function(event) {
589
613
" fingerprint" : " 1746566023960" ,
590
614
" parentFolderId" : " 36" ,
591
615
" formatValue" : {}
616
+ },
617
+ {
618
+ " accountId" : " 6054360526" ,
619
+ " containerId" : " 218106977" ,
620
+ " variableId" : " 59" ,
621
+ " name" : " DLV - audioContentType" ,
622
+ " type" : " v" ,
623
+ " parameter" : [
624
+ {
625
+ " type" : " INTEGER" ,
626
+ " key" : " dataLayerVersion" ,
627
+ " value" : " 2"
628
+ },
629
+ {
630
+ " type" : " BOOLEAN" ,
631
+ " key" : " setDefaultValue" ,
632
+ " value" : " false"
633
+ },
634
+ {
635
+ " type" : " TEMPLATE" ,
636
+ " key" : " name" ,
637
+ " value" : " audioContentType"
638
+ }
639
+ ],
640
+ " fingerprint" : " 1747102190814" ,
641
+ " parentFolderId" : " 36" ,
642
+ " formatValue" : {}
592
643
}
593
644
],
594
645
" folder" : [
@@ -607,7 +658,7 @@ window.addEventListener('message', function(event) {
607
658
" fingerprint" : " 1746252451511"
608
659
}
609
660
],
610
- "fingerprint" : " 1746937401785 " ,
661
+ " fingerprint" : " 1747103306426 " ,
611
662
" tagManagerUrl" : " https://tagmanager.google.com/#/versions/accounts/6054360526/containers/218106977/versions/0?apiLink=version"
612
663
}
613
664
}
0 commit comments