Repository navigation
Expand file tree
/
Copy pathscript.js
More file actions
90 lines (78 loc) · 3.21 KB
/
Copy pathscript.js
File metadata and controls
90 lines (78 loc) · 3.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
// Anonymous usage log to a private Google Sheet. See docs/architecture.md.
// Keep false until the Apps Script URL is set and privacy.html is live.
const TELEMETRY_ENABLED = true;
const TELEMETRY_URL = 'https://script.google.com/macros/s/AKfycbw7zVdwa3icuWfnUbyH5ygsCWTrAZQleRYg_UbqRiLwsHKseu2bbYJzAQcBrYNZfJKFKw/exec';
// Never send the pasted debug JSON. Only these fields.
function logEvent(outcome, adVideoId, clipboardOk) {
if (!TELEMETRY_ENABLED || !navigator.sendBeacon) return;
try {
const body = JSON.stringify({
outcome: outcome,
ad_id: adVideoId || null,
clipboard: clipboardOk,
tz: Intl.DateTimeFormat().resolvedOptions().timeZone
});
navigator.sendBeacon(TELEMETRY_URL, new Blob([body], { type: 'text/plain' }));
} catch (err) {
// Logging must never break the copy flow.
}
}
function showLink(resultDiv, message, adUrl) {
const p = document.createElement('p');
const a = document.createElement('a');
a.href = adUrl;
a.target = '_blank';
a.rel = 'noopener';
a.textContent = adUrl;
p.append(message, a);
resultDiv.replaceChildren(p);
}
const YOUTUBE_VIDEO_ID = /^[A-Za-z0-9_-]{11}$/;
const AD_VIDEO_ID_FIELDS = ['addocid', 'ad_docid', 'addebug_videoId'];
const NON_VIDEO_AD_IDS = new Set(['empty_video']);
function getAdVideoId(debugData) {
for (const field of AD_VIDEO_ID_FIELDS) {
const value = debugData && debugData[field];
if (typeof value === 'string' && value.trim()) return value.trim();
}
return null;
}
async function searchAd() {
const debugInfo = document.getElementById('debugInfo').value.trim();
const resultDiv = document.getElementById('result');
if (!debugInfo) {
resultDiv.textContent = 'Paste YouTube ad debug info, then try again.';
logEvent('invalid_json', null, null);
return;
}
let debugData;
try {
debugData = JSON.parse(debugInfo);
} catch (error) {
resultDiv.textContent = 'This does not look like YouTube debug info. While the ad is playing, right-click the video and choose “Copy debug info”.';
logEvent('invalid_json', null, null);
return;
}
const adVideoId = getAdVideoId(debugData);
if (!adVideoId) {
resultDiv.textContent = 'No ad video ID was found. Copy the debug info while a video ad is playing, then try again.';
logEvent('missing_addocid', null, null);
return;
}
if (!YOUTUBE_VIDEO_ID.test(adVideoId) || NON_VIDEO_AD_IDS.has(adVideoId)) {
resultDiv.textContent = 'This ad does not have a playable YouTube video ID. It may be an image, app, or interactive ad.';
logEvent('missing_addocid', null, null);
return;
}
const adUrl = `https://youtu.be/${encodeURIComponent(adVideoId)}`;
try {
await navigator.clipboard.writeText(adUrl);
showLink(resultDiv, 'Link copied to clipboard: ', adUrl);
logEvent('success', adVideoId, true);
alert('Link copied to clipboard!');
} catch (err) {
console.error('Error copying URL: ', err);
showLink(resultDiv, "Error copying to clipboard. Here's your link: ", adUrl);
logEvent('success', adVideoId, false);
}
}