Skill Tracer
Skills › Marketing Skills › conversion-tracking › detect-file-download.json

detect-file-download.json

81 lines · skills/conversion-tracking/assets/gtm-recipes/detect/detect-file-download.json at 88c79f6

1{
2 "exportFormatVersion": 2,
3 "containerVersion": {
4 "path": "accounts/0/containers/0",
5 "accountId": "0",
6 "containerId": "0",
7 "containerVersionId": "0",
8 "container": {
9 "path": "accounts/0/containers/0",
10 "accountId": "0",
11 "containerId": "0",
12 "name": "Conversion Detection - File download",
13 "publicId": "GTM-XXXXXXX",
14 "usageContext": [
15 "WEB"
16 ],
17 "fingerprint": "0",
18 "tagManagerUrl": "https://tagmanager.google.com/#/container/accounts/0/containers/0/workspaces/0"
19 },
20 "tag": [
21 {
22 "accountId": "0",
23 "containerId": "0",
24 "tagId": "1",
25 "name": "Conversion Detection - File download Listener",
26 "type": "html",
27 "parameter": [
28 {
29 "type": "TEMPLATE",
30 "key": "html",
31 "value": "<script>\n(function () {\n if (window.__ctDetectFileDownload) return;\n window.__ctDetectFileDownload = true;\n window.dataLayer = window.dataLayer || [];\n\n /* For gated content that is NOT gated: price lists, brochures, spec\n sheets, lead magnets served as a direct link. If the download sits\n behind a form, track the form instead — that is where the lead is.\n\n GA4 already collects file_download as an enhanced measurement event.\n Use this when you need the same signal in Google Ads or Meta, which\n do not. */\n\n // EDIT if you serve other formats.\n var EXTENSIONS = [\n 'pdf', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx',\n 'csv', 'zip', 'rar', '7z', 'dmg', 'exe', 'pkg',\n 'mp3', 'mp4', 'mov', 'wav', 'txt', 'rtf'\n ];\n\n var DEDUPE_MS = 2000;\n var lastUrl = null;\n var lastAt = 0;\n\n function extensionOf(url) {\n try {\n // Strip query and hash before reading the extension, so\n // /brochure.pdf?utm_source=x still resolves to \"pdf\".\n var path = String(url || '').split('#')[0].split('?')[0];\n var name = path.substring(path.lastIndexOf('/') + 1);\n var dot = name.lastIndexOf('.');\n if (dot < 0) return null;\n var ext = name.substring(dot + 1).toLowerCase();\n for (var i = 0; i < EXTENSIONS.length; i++) {\n if (EXTENSIONS[i] === ext) return ext;\n }\n } catch (e) { /* fall through */ }\n return null;\n }\n\n function fileNameOf(url) {\n try {\n var path = String(url || '').split('#')[0].split('?')[0];\n return decodeURIComponent(path.substring(path.lastIndexOf('/') + 1));\n } catch (e) {\n return '';\n }\n }\n\n function handleClick(event) {\n try {\n if (event.button !== undefined && event.button !== 0) return;\n if (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return;\n\n var target = event.target;\n if (!target || !target.closest) return;\n\n var link = target.closest('a[href]');\n if (!link) return;\n\n // Resolve relative hrefs against the current page. .href does this for\n // us where available; getAttribute would leave \"/files/x.pdf\" relative.\n var url = link.href || link.getAttribute('href');\n if (!url) return;\n\n // An anchor carrying the download attribute is a download regardless\n // of extension, so honour that too.\n var ext = extensionOf(url);\n var forced = link.hasAttribute && link.hasAttribute('download');\n if (!ext && !forced) return;\n\n var now = new Date().getTime();\n if (url === lastUrl && (now - lastAt) < DEDUPE_MS) return;\n lastUrl = url;\n lastAt = now;\n\n window.dataLayer.push({\n event: 'file_download',\n file_name: fileNameOf(url),\n file_extension: ext || '',\n file_url: url,\n link_text: (link.textContent || '').trim().slice(0, 100),\n page_path: window.location.pathname\n });\n } catch (e) {\n // Never throw back into the page's own click handling.\n }\n }\n\n document.addEventListener('click', handleClick, false);\n})();\n</script>"
32 },
33 {
34 "type": "BOOLEAN",
35 "key": "supportDocumentWrite",
36 "value": "false"
37 }
38 ],
39 "firingTriggerId": [
40 "2147479553"
41 ],
42 "tagFiringOption": "ONCE_PER_EVENT",
43 "monitoringMetadata": {
44 "type": "MAP"
45 },
46 "consentSettings": {
47 "consentStatus": "NOT_SET"
48 }
49 }
50 ],
51 "trigger": [
52 {
53 "accountId": "0",
54 "containerId": "0",
55 "triggerId": "2",
56 "name": "CE - File download",
57 "type": "CUSTOM_EVENT",
58 "customEventFilter": [
59 {
60 "type": "EQUALS",
61 "parameter": [
62 {
63 "type": "TEMPLATE",
64 "key": "arg0",
65 "value": "{{_event}}"
66 },
67 {
68 "type": "TEMPLATE",
69 "key": "arg1",
70 "value": "file_download"
71 }
72 ]
73 }
74 ],
75 "filter": []
76 }
77 ],
78 "variable": [],
79 "fingerprint": "0"
80 }