Return YouTube Comment Username

This is to change the handle in the YouTube comments section to a username.

当前为 2023-05-08 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Return YouTube Comment Username
  3. // @name:ja YouTubeコメント欄の名前を元に戻す
  4. // @version 0.2.1
  5. // @author yakisova41
  6. // @license MIT
  7. // @namespace https://yt-returnname-api.pages.dev/extension/
  8. // @description This is to change the handle in the YouTube comments section to a username.
  9. // @description:ja YouTubeのコメント欄の名前がハンドル(@...)表記になってしまった場合に、元のユーザーネームに上書きします。
  10. // @match https://www.youtube.com/*
  11. // @grant none
  12. // ==/UserScript==
  13.  
  14. "use strict";
  15. (() => {
  16. // src/getUserName.ts
  17. async function getUserName(id) {
  18. const data = await fetch(
  19. `https://www.youtube.com/youtubei/v1/browse?key=AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8&prettyPrint=false`,
  20. {
  21. method: "POST",
  22. headers: {
  23. accept: "*/*",
  24. "accept-encoding": "gzip, deflate, br",
  25. "accept-language": "ja",
  26. "content-type": "application/json",
  27. 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`,
  28. dnt: "1",
  29. referer: `https://www.youtube.com/channel/${id}`,
  30. "sec-ch-ua": `"Chromium";v="110", "Not A(Brand";v="24", "Google Chrome";v="110"`,
  31. "sec-ch-ua-arch": "x86",
  32. "sec-ch-ua-bitness": "64",
  33. "sec-ch-ua-full-version": "110.0.5481.104",
  34. "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"`,
  35. "sec-ch-ua-mobile": "?0",
  36. "sec-ch-ua-platform": "Windows",
  37. "sec-ch-ua-platform-version": "15.0.0",
  38. "sec-ch-ua-wow64": "?0",
  39. "sec-fetch-dest": "empty",
  40. "sec-fetch-mode": "same-origin",
  41. "sec-fetch-site": "same-origin",
  42. "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",
  43. "x-client-data": "x-client-data",
  44. "x-goog-authuser": "0",
  45. "x-goog-visitor-id": "visitorData",
  46. "x-origin": "https://www.youtube.com",
  47. "x-youtube-bootstrap-logged-in": "true",
  48. "x-youtube-client-name": "1",
  49. "x-youtube-client-version": "2.20230217.01.00"
  50. },
  51. body: JSON.stringify({
  52. context: {
  53. client: {
  54. hl: "ja",
  55. gl: "JP",
  56. remoteHost: "1919:8a10:1145:1419:e1c9:b81a:09db:ff3a",
  57. deviceMake: "",
  58. deviceModel: "",
  59. visitorData: "visitorData",
  60. 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)",
  61. clientName: "WEB",
  62. clientVersion: "2.20230217.01.00",
  63. osName: "Windows",
  64. osVersion: "10.0",
  65. originalUrl: "https://www.youtube.com/@FUCK_YOUTUBE/channels",
  66. platform: "DESKTOP",
  67. clientFormFactor: "UNKNOWN_FORM_FACTOR",
  68. configInfo: {
  69. appInstallData: "appInstallData"
  70. },
  71. userInterfaceTheme: "USER_INTERFACE_THEME_DARK",
  72. timeZone: "Asia/Tokyo",
  73. browserName: "Chrome",
  74. browserVersion: "110.0.0.0",
  75. 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",
  76. deviceExperimentId: "deviceExperimentId",
  77. screenWidthPoints: 599,
  78. screenHeightPoints: 937,
  79. screenPixelDensity: 1,
  80. screenDensityFloat: 1,
  81. utcOffsetMinutes: 540,
  82. memoryTotalKbytes: "8000000",
  83. mainAppWebInfo: {
  84. graftUrl: "/@FUCK_YOUTUBE/channels",
  85. pwaInstallabilityStatus: "PWA_INSTALLABILITY_STATUS_CAN_BE_INSTALLED",
  86. webDisplayMode: "WEB_DISPLAY_MODE_BROWSER",
  87. isWebNativeShareAvailable: true
  88. }
  89. },
  90. user: { lockedSafetyMode: false },
  91. request: {
  92. useSsl: true,
  93. internalExperimentFlags: [],
  94. consistencyTokenJars: []
  95. },
  96. clickTracking: {
  97. clickTrackingParams: "UnkoBuuriiiiiiiicuuusssaiMAJIDE="
  98. },
  99. adSignalsInfo: {
  100. params: [
  101. { key: "dt", value: "1145141919810" },
  102. { key: "flash", value: "0" },
  103. { key: "frm", value: "0" },
  104. { key: "u_tz", value: "540" },
  105. { key: "u_his", value: "1" },
  106. { key: "u_h", value: "1080" },
  107. { key: "u_w", value: "1920" },
  108. { key: "u_ah", value: "1040" },
  109. { key: "u_aw", value: "1920" },
  110. { key: "u_cd", value: "24" },
  111. { key: "bc", value: "31" },
  112. { key: "bih", value: "937" },
  113. { key: "biw", value: "582" },
  114. {
  115. key: "brdim",
  116. value: "-1920,0,-1920,0,1920,0,1920,1040,599,937"
  117. },
  118. { key: "vis", value: "1" },
  119. { key: "wgl", value: "true" },
  120. { key: "ca_type", value: "image" }
  121. ]
  122. }
  123. },
  124. browseId: id,
  125. params: "YajuSenpaiInmu1919%3D"
  126. })
  127. }
  128. ).then(async (res) => await res.text()).then((text) => {
  129. const data2 = JSON.parse(text);
  130. const name = data2.header.c4TabbedHeaderRenderer.title;
  131. return name;
  132. });
  133. return data;
  134. }
  135.  
  136. // src/index.ts
  137. function main() {
  138. let commentReplaceInterval = 0;
  139. const pageChangeOb = pageChangeObserver();
  140. pageChangeOb.addPageChangeListener((newHref) => {
  141. const pageName = new URL(newHref).pathname.split("/")[1];
  142. if (pageName === "watch" || pageName === "shorts") {
  143. clearInterval(commentReplaceInterval);
  144. commentReplaceInterval = runCommentsReplace(pageChangeOb);
  145. }
  146. });
  147. const style = document.createElement("style");
  148. document.head.appendChild(style);
  149. style.innerHTML = `#author-text > span:nth-child(1) ,ytd-author-comment-badge-renderer > #name > #channel-name > #container > #text-container > yt-formatted-string{
  150. display:none;
  151. }`;
  152. }
  153. function runCommentsReplace(pageChangeOb) {
  154. return window.setInterval(() => {
  155. const authorSpan = document.querySelector(
  156. "#author-text > span:nth-child(1):not(.name-replaced)"
  157. );
  158. if (authorSpan !== null) {
  159. authorSpan.classList.add("name-replaced");
  160. const channelLink2 = authorSpan.parentElement;
  161. const href = channelLink2?.getAttribute("href");
  162. if (channelLink2 !== null && typeof href === "string") {
  163. void getUserName(href.split("/")[2]).then((name) => {
  164. replacedElement(authorSpan, name);
  165. });
  166. }
  167. }
  168. const mention = document.querySelector(
  169. `#content-text > a.yt-formatted-string[dir="auto"]:not(.name-replaced)`
  170. );
  171. if (mention !== null) {
  172. mention.classList.add("name-replaced");
  173. if (mention.innerHTML.match("@.*") !== null) {
  174. mention.removeAttribute("dir");
  175. const href = mention.getAttribute("href");
  176. if (href !== null) {
  177. void getUserName(href.split("/")[2]).then((name) => {
  178. mention.innerHTML = "@" + name;
  179. });
  180. }
  181. }
  182. }
  183. const channelNameSpan = document.querySelector(
  184. "ytd-author-comment-badge-renderer > #name > #channel-name > #container > #text-container > yt-formatted-string:not(.name-replaced)"
  185. );
  186. const channelLink = channelNameSpan?.parentElement?.parentElement?.parentElement?.parentElement;
  187. if (channelLink !== null && channelNameSpan !== null) {
  188. channelNameSpan.classList.add("name-replaced");
  189. const href = channelLink?.getAttribute("href");
  190. if (channelLink !== null && typeof href === "string") {
  191. void getUserName(href.split("/")[2]).then((name) => {
  192. replacedElement(channelNameSpan, name);
  193. });
  194. }
  195. }
  196. });
  197. }
  198. function pageChangeObserver() {
  199. let beforeHref = "";
  200. const body = document.querySelector("body");
  201. const pageChangeListeners = [];
  202. if (body !== null) {
  203. const observer = new MutationObserver(() => {
  204. const href = location.href;
  205. if (href !== beforeHref) {
  206. pageChangeListeners.forEach((listener) => {
  207. listener(href);
  208. });
  209. }
  210. beforeHref = href;
  211. });
  212. observer.observe(body, {
  213. childList: true,
  214. subtree: true
  215. });
  216. }
  217. return {
  218. addPageChangeListener: (listener) => {
  219. pageChangeListeners.push(listener);
  220. return pageChangeListeners.length - 1;
  221. },
  222. removePageChangeListener: (key) => {
  223. pageChangeListeners.splice(key, 1);
  224. }
  225. };
  226. }
  227. function replacedElement(nameElem, name) {
  228. const className = "shit-youtube-handle-name";
  229. const parent = nameElem.parentElement;
  230. if (parent !== null) {
  231. const replacedNameElem = parent.querySelector(`.${className}`);
  232. if (replacedNameElem !== null) {
  233. replacedNameElem.innerHTML = name;
  234. } else {
  235. const replacedNameElem2 = document.createElement("span");
  236. replacedNameElem2.className = nameElem.className;
  237. replacedNameElem2.classList.add(className);
  238. replacedNameElem2.innerHTML = name;
  239. parent.appendChild(replacedNameElem2);
  240. }
  241. }
  242. }
  243. main();
  244. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址