Return YouTube Comment Username

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

当前为 2023-06-21 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Return YouTube Comment Username
  3. // @name:ja YouTubeコメント欄の名前を元に戻す
  4. // @version 0.3.4
  5. // @author yakisova41
  6. // @license MIT
  7. // @icon data:image/png;base64,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
  8. // @namespace https://yt-returnname-api.pages.dev/extension/
  9. // @description This is to change the handle in the YouTube comments section to a username.
  10. // @description:ja YouTubeのコメント欄の名前がハンドル(@...)表記になってしまった場合に、元のユーザーネームに上書きします。
  11. // @match https://www.youtube.com/*
  12. // @grant unsafeWindow
  13. // @run-at document-end
  14. // ==/UserScript==
  15.  
  16. const scriptString = `// 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. const handleYtAction = (e) => {
  139. const { actionName } = e.detail;
  140. switch (actionName) {
  141. case "yt-append-continuation-items-action":
  142. handleYtAppendContinuationItemsAction(e.detail);
  143. break;
  144. case "yt-reload-continuation-items-command":
  145. handleYtReloadContinuationItemsCommand(e.detail);
  146. break;
  147. case "yt-history-load":
  148. handleYtHistory(e.detail);
  149. break;
  150. case "yt-get-multi-page-menu-action":
  151. handleYtGetMultiPageMenuAction(e.detail);
  152. break;
  153. case "yt-create-comment-action":
  154. handleYtCreateCommentAction(e.detail);
  155. break;
  156. }
  157. };
  158. document.addEventListener("yt-action", handleYtAction);
  159. document.addEventListener("yt-navigate-finish", ({ detail }) => {
  160. document.removeEventListener("yt-action", handleYtAction);
  161. document.addEventListener("yt-action", handleYtAction);
  162. });
  163. }
  164. function handleYtAppendContinuationItemsAction(detail) {
  165. const continuationItems = detail.args[0].appendContinuationItemsAction.continuationItems;
  166. if (isCommentRenderer(continuationItems)) {
  167. const replyDetail = detail;
  168. setTimeout(() => {
  169. rewriteReplytNameFromContinuationItems(
  170. replyDetail.args[0].appendContinuationItemsAction.continuationItems
  171. );
  172. }, 1);
  173. } else {
  174. const commentDetail = detail;
  175. setTimeout(() => {
  176. rewriteCommentNameFromContinuationItems(
  177. commentDetail.args[0].appendContinuationItemsAction.continuationItems
  178. );
  179. }, 100);
  180. }
  181. }
  182. function handleYtReloadContinuationItemsCommand(detail) {
  183. const reloadDetail = detail;
  184. const { slot } = reloadDetail.args[0].reloadContinuationItemsCommand;
  185. if (slot === "RELOAD_CONTINUATION_SLOT_BODY") {
  186. const continuationItems = reloadDetail.args[0].reloadContinuationItemsCommand.continuationItems;
  187. setTimeout(() => {
  188. rewriteCommentNameFromContinuationItems(continuationItems);
  189. }, 100);
  190. }
  191. }
  192. function handleYtHistory(detail) {
  193. const historyDetail = detail;
  194. const continuationItems = historyDetail.args[1].historyEntry?.rootData.response.contents.twoColumnWatchNextResults?.results?.results?.contents[3]?.itemSectionRenderer?.contents;
  195. if (continuationItems !== void 0) {
  196. setTimeout(() => {
  197. rewriteCommentNameFromContinuationItems(continuationItems);
  198. }, 100);
  199. }
  200. }
  201. function handleYtGetMultiPageMenuAction(detail) {
  202. const getMultiPageMenuDetail = detail;
  203. const continuationItems = getMultiPageMenuDetail.args[0].getMultiPageMenuAction.menu.multiPageMenuRenderer.sections[1].itemSectionRenderer?.contents;
  204. const highLightedReplyRenderer = getMultiPageMenuDetail.args[0]?.getMultiPageMenuAction?.menu?.multiPageMenuRenderer.sections[1].itemSectionRenderer?.contents[0]?.commentThreadRenderer.replies?.commentRepliesRenderer?.teaserContents[0]?.commentRenderer;
  205. if (continuationItems !== void 0) {
  206. setTimeout(() => {
  207. rewriteCommentNameFromContinuationItems(continuationItems);
  208. if (highLightedReplyRenderer !== void 0) {
  209. let isContainer = highLightedReplyRenderer.authorIsChannelOwner;
  210. if (highLightedReplyRenderer.authorCommentBadge !== void 0) {
  211. isContainer = true;
  212. }
  213. rewriteHighlightedReply(
  214. highLightedReplyRenderer.trackingParams,
  215. isContainer,
  216. highLightedReplyRenderer.authorEndpoint.browseEndpoint.browseId
  217. );
  218. }
  219. }, 100);
  220. }
  221. }
  222. function rewriteHighlightedReply(trackedParams, isContainer, userId) {
  223. const elem = findElementByTrackingParams(
  224. trackedParams,
  225. "ytd-comment-renderer"
  226. );
  227. const rewriteHighlightedReplyElem = (elem2) => {
  228. nameRewriteOfCommentRenderer(elem2, isContainer, userId);
  229. };
  230. if (elem === null) {
  231. void reSearchElement(trackedParams, "ytd-comment-renderer").then((elem2) => {
  232. rewriteHighlightedReplyElem(elem2);
  233. });
  234. } else {
  235. rewriteHighlightedReplyElem(elem);
  236. }
  237. }
  238. function handleYtCreateCommentAction(detail) {
  239. const createCommentDetail = detail;
  240. const continuationItems = [
  241. {
  242. commentThreadRenderer: createCommentDetail.args[0].createCommentAction.contents.commentThreadRenderer
  243. }
  244. ];
  245. setTimeout(() => {
  246. rewriteCommentNameFromContinuationItems(continuationItems);
  247. }, 100);
  248. }
  249. function rewriteReplytNameFromContinuationItems(continuationItems) {
  250. continuationItems.forEach((continuationItem) => {
  251. const { commentRenderer } = continuationItem;
  252. if (commentRenderer !== void 0) {
  253. const replyCommentRenderer = findElementByTrackingParams(
  254. commentRenderer.trackingParams,
  255. "ytd-comment-renderer"
  256. );
  257. const reWriteReplyCommentRenderer = (replyCommentRenderer2) => {
  258. let isContainer = commentRenderer.authorIsChannelOwner;
  259. if (commentRenderer.authorCommentBadge !== void 0) {
  260. isContainer = true;
  261. }
  262. nameRewriteOfCommentRenderer(
  263. replyCommentRenderer2,
  264. isContainer,
  265. commentRenderer.authorEndpoint.browseEndpoint.browseId
  266. );
  267. mentionRewriteOfCommentRenderer(replyCommentRenderer2);
  268. };
  269. if (replyCommentRenderer !== null) {
  270. reWriteReplyCommentRenderer(replyCommentRenderer);
  271. } else {
  272. void reSearchElement(
  273. commentRenderer.trackingParams,
  274. "ytd-comment-renderer"
  275. ).then((el) => {
  276. reWriteReplyCommentRenderer(el);
  277. });
  278. }
  279. }
  280. });
  281. }
  282. function rewriteCommentNameFromContinuationItems(continuationItems) {
  283. continuationItems.forEach((continuationItem) => {
  284. const { commentThreadRenderer } = continuationItem;
  285. if (commentThreadRenderer !== void 0) {
  286. const { trackingParams } = commentThreadRenderer;
  287. const commentElem = findElementByTrackingParams(
  288. trackingParams,
  289. "#comments > #sections > #contents > ytd-comment-thread-renderer"
  290. );
  291. const reWriteCommentElem = (commentElem2) => {
  292. const commentRenderer = commentElem2?.querySelector(
  293. "ytd-comment-renderer"
  294. );
  295. if (commentRenderer !== null && commentRenderer !== void 0) {
  296. let isContainer = commentThreadRenderer.comment.commentRenderer.authorIsChannelOwner;
  297. if (commentThreadRenderer.comment.commentRenderer.authorCommentBadge !== void 0) {
  298. isContainer = true;
  299. }
  300. nameRewriteOfCommentRenderer(
  301. commentRenderer,
  302. isContainer,
  303. commentThreadRenderer.comment.commentRenderer.authorEndpoint.browseEndpoint.browseId
  304. );
  305. }
  306. };
  307. if (commentElem !== null) {
  308. reWriteCommentElem(commentElem);
  309. } else {
  310. void reSearchElement(
  311. trackingParams,
  312. "ytd-comment-thread-renderer"
  313. ).then((commentElem2) => {
  314. reWriteCommentElem(commentElem2);
  315. });
  316. }
  317. }
  318. });
  319. }
  320. function nameRewriteOfCommentRenderer(commentRenderer, isNameContainerRender, userId) {
  321. let nameElem = commentRenderer.querySelector(
  322. "#body > #main > #header > #header-author > h3 > a > span"
  323. );
  324. if (isNameContainerRender) {
  325. nameElem = commentRenderer.querySelector(
  326. "#body > #main > #header > #header-author > #author-comment-badge > ytd-author-comment-badge-renderer > a > #channel-name > #container > #text-container > yt-formatted-string"
  327. );
  328. }
  329. void getUserName(userId).then((name) => {
  330. if (nameElem !== null) {
  331. nameElem.textContent = name;
  332. }
  333. });
  334. }
  335. function mentionRewriteOfCommentRenderer(commentRenderer) {
  336. const aTags = commentRenderer.querySelectorAll(
  337. "#body > #main > #comment-content > ytd-expander > #content > #content-text > a"
  338. );
  339. aTags.forEach((aTag) => {
  340. if (aTag.textContent?.match("@.*") !== null) {
  341. const href = aTag.getAttribute("href");
  342. if (href !== null) {
  343. void getUserName(href.split("/")[2]).then((name) => {
  344. aTag.textContent = \`@\${name} \`;
  345. });
  346. }
  347. }
  348. });
  349. }
  350. function isCommentRenderer(continuationItems) {
  351. if (continuationItems.length > 0) {
  352. if (continuationItems[0].hasOwnProperty("commentThreadRenderer")) {
  353. return false;
  354. }
  355. if (continuationItems[0].hasOwnProperty("commentRenderer")) {
  356. return true;
  357. }
  358. }
  359. return false;
  360. }
  361. function findElementByTrackingParams(trackingParams, elementSelector) {
  362. let returnElement = null;
  363. const elems = document.querySelectorAll(elementSelector);
  364. elems.forEach((elem) => {
  365. if (elem.trackedParams === trackingParams) {
  366. returnElement = elem;
  367. }
  368. });
  369. return returnElement;
  370. }
  371. async function reSearchElement(trackingParams, elementType) {
  372. return await new Promise((resolve) => {
  373. let isFinding = true;
  374. const search = () => {
  375. const el = findElementByTrackingParams(trackingParams, elementType);
  376. if (el !== null) {
  377. resolve(el);
  378. isFinding = false;
  379. }
  380. if (isFinding) {
  381. setTimeout(() => {
  382. search();
  383. }, 100);
  384. }
  385. };
  386. search();
  387. });
  388. }
  389.  
  390. // node_modules/ts-extension-builder/tmp/entry.ts
  391. var args = {};
  392. if (typeof GM_info !== "undefined" && GM_info.script.grant !== void 0) {
  393. GM_info.script.grant.forEach((propatyName) => {
  394. let keyName = propatyName.split("GM_")[1];
  395. if (keyName === "xmlhttpRequest") {
  396. keyName = "xmlHttpRequest";
  397. }
  398. args[propatyName] = GM[keyName];
  399. });
  400. }
  401. main(args);
  402. `;
  403. const script = document.createElement("script");
  404. script.innerHTML = scriptString
  405. unsafeWindow.document.body.appendChild(script)