Skill Tracer
Skills › Marketing Skills › conversion-tracking › detect-phone-click.json

detect-phone-click.json

81 lines · skills/conversion-tracking/assets/gtm-recipes/detect/detect-phone-click.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 - Phone call click",
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 - Phone call click Listener",
26 "type": "html",
27 "parameter": [
28 {
29 "type": "TEMPLATE",
30 "key": "html",
31 "value": "<script>\n(function () {\n if (window.__ctDetectPhoneClick) return;\n window.__ctDetectPhoneClick = true;\n window.dataLayer = window.dataLayer || [];\n\n // A click is a call INTENT, not a completed call. On desktop especially,\n // many tel: clicks never become a conversation. Count it as a lead signal,\n // and prefer a call tracking number if you need answered-call accuracy.\n\n // Ignore a repeat click on the same number inside this window. Impatient\n // double-taps on mobile are common and would otherwise double count.\n var DEDUPE_MS = 2000;\n var lastNumber = null;\n var lastAt = 0;\n\n function normalise(href) {\n // tel:+61 (2) 1234-5678 -> +61212345678 . Keeps a leading +, drops the\n // punctuation humans put in phone numbers so dedupe compares like for like.\n var raw = String(href || '').replace(/^tel:/i, '');\n try { raw = decodeURIComponent(raw); } catch (e) { /* leave as-is */ }\n var plus = raw.trim().charAt(0) === '+' ? '+' : '';\n return plus + raw.replace(/[^0-9]/g, '');\n }\n\n function handleClick(event) {\n try {\n // Left click only, and not a modified click that opens elsewhere.\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 // closest() because the click usually lands on an icon or span INSIDE\n // the anchor, not the anchor itself.\n var link = target.closest('a[href^=\"tel:\"], a[href^=\"TEL:\"]');\n if (!link) return;\n\n var number = normalise(link.getAttribute('href'));\n if (!number) return;\n\n var now = new Date().getTime();\n if (number === lastNumber && (now - lastAt) < DEDUPE_MS) return;\n lastNumber = number;\n lastAt = now;\n\n // PII: if the site shows visitor-specific numbers (an account page, a\n // CRM-driven \"your rep\" number), drop phone_number and link_text here.\n window.dataLayer.push({\n event: 'phone_click',\n phone_number: number,\n // The visible text, useful when a site shows different numbers per\n // location or campaign. Trimmed and capped so a whole button's worth\n // of markup text never lands in the dataLayer.\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 // Bubble phase: a tel: click has no validation to lose a race with, and\n // bubbling means anything that legitimately cancels the click wins first.\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 - Phone call click",
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": "phone_click"
71 }
72 ]
73 }
74 ],
75 "filter": []
76 }
77 ],
78 "variable": [],
79 "fingerprint": "0"
80 }