// ==UserScript==
// @name Return YouTube Comment Username
// @name:ja YouTubeコメント欄の名前を元に戻す
// @version 0.2.2
// @author yakisova41
// @license MIT
// @namespace https://yt-returnname-api.pages.dev/extension/
// @description This is to change the handle in the YouTube comments section to a username.
// @description:ja YouTubeのコメント欄の名前がハンドル(@...)表記になってしまった場合に、元のユーザーネームに上書きします。
// @match https://www.youtube.com/*
// @grant none
// ==/UserScript==
// src/getUserName.ts
async function getUserName(id) {
const data = await fetch(
`https://www.youtube.com/youtubei/v1/browse?key=AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8&prettyPrint=false`,
{
method: "POST",
headers: {
accept: "*/*",
"accept-encoding": "gzip, deflate, br",
"accept-language": "ja",
"content-type": "application/json",
cookie: `GPS=1; YSC=YajuSEnP; DEVICE_INFO=DEVICE_INFO; VISITOR_INFO1_LIVE=LLIIVVEE; PREF=f6=40000000&tz=Asia.Tokyo; ST-o2eza2=itct=itct&endpoint=%7B%22clickTrackingParams%22%3A%22CBQQ8JMBGAciEwjNqtCAASAhXnm1YBHABY%3D%22%2C%22commandMetadata%22%3A%7B%22webCommandMetadata%22%3A%7B%22url%22%3A%22%2F%40FUCKYOUTUBE%2Fchannels%22%2C%22webPageType%22%3A%22WEB_PAGE_TYPE_CHANNEL%22%2C%22rootVe%22%3A3611%2C%22apiUrl%22%3A%22%2Fyoutubei%2Fv1%2Fbrowse%22%7D%7D%2C%22browseEndpoint%22%3A%7B%22browseId%22%3A%22${id}%22%2C%22params%22%3A%22EghjaGFubmVsc_IGBAoCUgA%253D%22%2C%22canonicalBaseUrl%22%3A%22%2F%40FUCK_YOUTUBE%22%7D%7D`,
dnt: "1",
referer: `https://www.youtube.com/channel/${id}`,
"sec-ch-ua": `"Chromium";v="110", "Not A(Brand";v="24", "Google Chrome";v="110"`,
"sec-ch-ua-arch": "x86",
"sec-ch-ua-bitness": "64",
"sec-ch-ua-full-version": "110.0.5481.104",
"sec-ch-ua-full-version-list": `"Chromium";v="110.0.5481.104", "Not A(Brand";v="24.0.0.0", "Google Chrome";v="110.0.5481.104"`,
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": "Windows",
"sec-ch-ua-platform-version": "15.0.0",
"sec-ch-ua-wow64": "?0",
"sec-fetch-dest": "empty",
"sec-fetch-mode": "same-origin",
"sec-fetch-site": "same-origin",
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36",
"x-client-data": "x-client-data",
"x-goog-authuser": "0",
"x-goog-visitor-id": "visitorData",
"x-origin": "https://www.youtube.com",
"x-youtube-bootstrap-logged-in": "true",
"x-youtube-client-name": "1",
"x-youtube-client-version": "2.20230217.01.00"
},
body: JSON.stringify({
context: {
client: {
hl: "ja",
gl: "JP",
remoteHost: "1919:8a10:1145:1419:e1c9:b81a:09db:ff3a",
deviceMake: "",
deviceModel: "",
visitorData: "visitorData",
userAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36,gzip(gfe)",
clientName: "WEB",
clientVersion: "2.20230217.01.00",
osName: "Windows",
osVersion: "10.0",
originalUrl: "https://www.youtube.com/@FUCK_YOUTUBE/channels",
platform: "DESKTOP",
clientFormFactor: "UNKNOWN_FORM_FACTOR",
configInfo: {
appInstallData: "appInstallData"
},
userInterfaceTheme: "USER_INTERFACE_THEME_DARK",
timeZone: "Asia/Tokyo",
browserName: "Chrome",
browserVersion: "110.0.0.0",
acceptHeader: "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
deviceExperimentId: "deviceExperimentId",
screenWidthPoints: 599,
screenHeightPoints: 937,
screenPixelDensity: 1,
screenDensityFloat: 1,
utcOffsetMinutes: 540,
memoryTotalKbytes: "8000000",
mainAppWebInfo: {
graftUrl: "/@FUCK_YOUTUBE/channels",
pwaInstallabilityStatus: "PWA_INSTALLABILITY_STATUS_CAN_BE_INSTALLED",
webDisplayMode: "WEB_DISPLAY_MODE_BROWSER",
isWebNativeShareAvailable: true
}
},
user: { lockedSafetyMode: false },
request: {
useSsl: true,
internalExperimentFlags: [],
consistencyTokenJars: []
},
clickTracking: {
clickTrackingParams: "UnkoBuuriiiiiiiicuuusssaiMAJIDE="
},
adSignalsInfo: {
params: [
{ key: "dt", value: "1145141919810" },
{ key: "flash", value: "0" },
{ key: "frm", value: "0" },
{ key: "u_tz", value: "540" },
{ key: "u_his", value: "1" },
{ key: "u_h", value: "1080" },
{ key: "u_w", value: "1920" },
{ key: "u_ah", value: "1040" },
{ key: "u_aw", value: "1920" },
{ key: "u_cd", value: "24" },
{ key: "bc", value: "31" },
{ key: "bih", value: "937" },
{ key: "biw", value: "582" },
{
key: "brdim",
value: "-1920,0,-1920,0,1920,0,1920,1040,599,937"
},
{ key: "vis", value: "1" },
{ key: "wgl", value: "true" },
{ key: "ca_type", value: "image" }
]
}
},
browseId: id,
params: "YajuSenpaiInmu1919%3D"
})
}
).then(async (res) => await res.text()).then((text) => {
const data2 = JSON.parse(text);
const name = data2.header.c4TabbedHeaderRenderer.title;
return name;
});
return data;
}
// src/handleToName.ts
async function handleToName(handle) {
const res = await fetch(`https://www.youtube.com/${handle}/about`);
const text = await res.text();
const parser = new DOMParser();
const dom = parser.parseFromString(text, "text/html");
const ogtitle = dom.querySelector(`meta[property="og:title"]`);
const name = ogtitle?.getAttribute("content");
if (typeof name === "string") {
return name;
} else {
return "ERROR";
}
}
// src/index.ts
function main() {
let commentReplaceInterval = 0;
const pageChangeOb = pageChangeObserver();
pageChangeOb.addPageChangeListener((newHref) => {
const pagePathArray = new URL(newHref).pathname.split("/");
switch (pagePathArray[1]) {
case "watch":
case "shorts":
case "post":
clearInterval(commentReplaceInterval);
commentReplaceInterval = runCommentsReplace(pageChangeOb);
break;
default:
if (pagePathArray[2] === "community") {
clearInterval(commentReplaceInterval);
commentReplaceInterval = runCommentsReplace(pageChangeOb);
} else {
clearInterval(commentReplaceInterval);
}
}
});
const style = document.createElement("style");
document.head.appendChild(style);
style.innerHTML = `#author-text > span:nth-child(1) ,ytd-author-comment-badge-renderer > #name > #channel-name > #container > #text-container > yt-formatted-string{
display:none;
}`;
}
function runCommentsReplace(pageChangeOb) {
return window.setInterval(() => {
const authorSpan = document.querySelector(
"#author-text > span:nth-child(1):not(.name-replaced)"
);
if (authorSpan !== null) {
authorSpan.classList.add("name-replaced");
const channelLink2 = authorSpan.parentElement;
const href = channelLink2?.getAttribute("href");
if (channelLink2 !== null && typeof href === "string") {
if (href.split("/")[1][0] === "@") {
void handleToName(href.split("/")[1]).then((name) => {
replacedElement(authorSpan, name);
});
} else {
void getUserName(href.split("/")[2]).then((name) => {
replacedElement(authorSpan, name);
});
}
}
}
const mention = document.querySelector(
`#content-text > a.yt-formatted-string[dir="auto"]:not(.name-replaced)`
);
if (mention !== null) {
mention.classList.add("name-replaced");
if (mention.innerHTML.match("@.*") !== null) {
mention.removeAttribute("dir");
const href = mention.getAttribute("href");
if (href !== null) {
void getUserName(href.split("/")[2]).then((name) => {
mention.innerHTML = "@" + name;
});
}
}
}
const channelNameSpan = document.querySelector(
"ytd-author-comment-badge-renderer > #name > #channel-name > #container > #text-container > yt-formatted-string:not(.name-replaced)"
);
const channelLink = channelNameSpan?.parentElement?.parentElement?.parentElement?.parentElement;
if (channelLink !== null && channelNameSpan !== null) {
channelNameSpan.classList.add("name-replaced");
const href = channelLink?.getAttribute("href");
if (channelLink !== null && typeof href === "string") {
void getUserName(href.split("/")[2]).then((name) => {
replacedElement(channelNameSpan, name);
});
}
}
});
}
function pageChangeObserver() {
let beforeHref = "";
const body = document.querySelector("body");
const pageChangeListeners = [];
if (body !== null) {
const observer = new MutationObserver(() => {
const href = location.href;
if (href !== beforeHref) {
pageChangeListeners.forEach((listener) => {
listener(href);
});
}
beforeHref = href;
});
observer.observe(body, {
childList: true,
subtree: true
});
}
return {
addPageChangeListener: (listener) => {
pageChangeListeners.push(listener);
return pageChangeListeners.length - 1;
},
removePageChangeListener: (key) => {
pageChangeListeners.splice(key, 1);
}
};
}
function replacedElement(nameElem, name) {
const className = "shit-youtube-handle-name";
const parent = nameElem.parentElement;
if (parent !== null) {
const replacedNameElem = parent.querySelector(`.${className}`);
if (replacedNameElem !== null) {
replacedNameElem.innerHTML = name;
} else {
const replacedNameElem2 = document.createElement("span");
replacedNameElem2.className = nameElem.className;
replacedNameElem2.classList.add(className);
replacedNameElem2.innerHTML = name;
parent.appendChild(replacedNameElem2);
}
}
}
main();
// node_modules/ts-extension-builder/tmp/entry.ts
var args = {};
if (typeof GM_info !== "undefined") {
GM_info.script.grant.forEach((propatyName) => {
let keyName = propatyName.split("GM_")[1];
if (keyName === "xmlhttpRequest") {
keyName = "xmlHttpRequest";
}
args[propatyName] = GM[keyName];
});
}
main(args);