恢復 YouTube 评论用户名

此脚本将 YouTube 评论部分中的“handle”替换为用户名

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

  1. // ==UserScript==
  2. // @name Return YouTube Comment Username
  3. // @name:ja YouTubeコメント欄の名前を元に戻す
  4. // @name:zh-CN 恢復 YouTube 评论用户名
  5. // @name:zh-TW 恢復 YouTube 評論名稱
  6. // @version 0.3.6
  7. // @author yakisova41
  8. // @license MIT
  9. // @icon data:image/png;base64,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
  10. // @namespace https://yt-returnname-api.pages.dev/extension/
  11. // @description This script replaces the "handle" in the YouTube comments section to user name
  12. // @description:ja YouTubeのコメント欄の名前をハンドル(@...)からユーザー名に書き換えます。
  13. // @description:zh-TW 此腳本將 YouTube 評論部分中的“handle”替換為用戶名
  14. // @description:zh-CN 此脚本将 YouTube 评论部分中的“handle”替换为用户名
  15. // @match https://www.youtube.com/*
  16. // @grant unsafeWindow
  17. // @run-at document-end
  18. // ==/UserScript==
  19.  
  20. const scriptString = `// src/utils/isCommentRenderer.ts
  21. function isCommentRenderer(continuationItems) {
  22. if (continuationItems.length > 0) {
  23. if (continuationItems[0].hasOwnProperty("commentThreadRenderer")) {
  24. return false;
  25. }
  26. if (continuationItems[0].hasOwnProperty("commentRenderer")) {
  27. return true;
  28. }
  29. }
  30. return false;
  31. }
  32.  
  33. // src/utils/findElementByTrackingParams.ts
  34. function findElementByTrackingParams(trackingParams, elementSelector) {
  35. let returnElement = null;
  36. const elems = document.querySelectorAll(elementSelector);
  37. elems.forEach((elem) => {
  38. if (elem.trackedParams === trackingParams) {
  39. returnElement = elem;
  40. }
  41. });
  42. return returnElement;
  43. }
  44. async function reSearchElement(trackingParams, selector) {
  45. return await new Promise((resolve) => {
  46. let isFinding = true;
  47. const search = () => {
  48. const el = findElementByTrackingParams(trackingParams, selector);
  49. if (el !== null) {
  50. resolve(el);
  51. isFinding = false;
  52. }
  53. if (isFinding) {
  54. setTimeout(() => {
  55. search();
  56. }, 100);
  57. }
  58. };
  59. search();
  60. });
  61. }
  62. function findElementAllByCommentId(commnetId, elementSelector) {
  63. const returnElements = [];
  64. const elems = document.querySelectorAll(elementSelector);
  65. elems.forEach((elem) => {
  66. if (elem.__data.data.commentId === commnetId) {
  67. returnElements.push(elem);
  68. }
  69. });
  70. return returnElements;
  71. }
  72. async function reSearchElementAllByCommentId(commnetId, selector) {
  73. return await new Promise((resolve) => {
  74. let isFinding = true;
  75. const search = () => {
  76. const el = findElementAllByCommentId(commnetId, selector);
  77. if (el !== null) {
  78. resolve(el);
  79. isFinding = false;
  80. }
  81. if (isFinding) {
  82. setTimeout(() => {
  83. search();
  84. }, 100);
  85. }
  86. };
  87. search();
  88. });
  89. }
  90.  
  91. // src/utils/escapeString.ts
  92. function escapeString(text) {
  93. return text.replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll(\`"\`, \`&quot;\`).replaceAll(\`'\`, \`&apos;\`);
  94. }
  95.  
  96. // src/utils/getUserName.ts
  97. async function getUserName(id) {
  98. const data = await fetch(
  99. \`https://www.youtube.com/youtubei/v1/browse?key=AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8&prettyPrint=false\`,
  100. {
  101. method: "POST",
  102. headers: {
  103. accept: "*/*",
  104. "accept-encoding": "gzip, deflate, br",
  105. "accept-language": "ja",
  106. "content-type": "application/json",
  107. dnt: "1",
  108. referer: \`https://www.youtube.com/channel/\${id}\`
  109. },
  110. body: JSON.stringify({
  111. context: {
  112. client: {
  113. hl: window.yt.config_.HL,
  114. gl: window.yt.config_.GL,
  115. remoteHost: "1919:8a10:1145:1419:e1c9:b81a:09db:ff3a",
  116. clientName: "WEB",
  117. clientVersion: "2.20230628.01.00",
  118. platform: "DESKTOP",
  119. 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"
  120. },
  121. user: { lockedSafetyMode: false },
  122. request: {
  123. useSsl: true,
  124. internalExperimentFlags: [],
  125. consistencyTokenJars: []
  126. },
  127. clickTracking: {
  128. clickTrackingParams: "UnkoBuuriiiiiiiicuuusssaiMAJIDE="
  129. }
  130. },
  131. browseId: id,
  132. params: "a"
  133. })
  134. }
  135. ).then(async (res) => await res.text()).then((text) => {
  136. const data2 = JSON.parse(text);
  137. const name = data2.header.c4TabbedHeaderRenderer.title;
  138. return name;
  139. });
  140. return data;
  141. }
  142.  
  143. // src/rewrites/rewriteOfCommentRenderer/nameRewriteOfCommentRenderer.ts
  144. function nameRewriteOfCommentRenderer(commentRenderer, isNameContainerRender, userId) {
  145. const commentRendererBody = commentRenderer.__shady_native_children[2];
  146. let nameElem = commentRendererBody.querySelector(
  147. "#main > #header > #header-author > h3 > a > span"
  148. );
  149. if (isNameContainerRender) {
  150. nameElem = commentRendererBody.__shady_native_children[1].querySelector(
  151. "#header > #header-author > #author-comment-badge > ytd-author-comment-badge-renderer > a > #channel-name > #container > #text-container > yt-formatted-string"
  152. );
  153. }
  154. void getUserName(userId).then((name) => {
  155. if (nameElem !== null) {
  156. if (isNameContainerRender) {
  157. nameElem.__shady_native_innerHTML = escapeString(name);
  158. } else {
  159. nameElem.textContent = escapeString(name);
  160. }
  161. }
  162. });
  163. }
  164.  
  165. // src/rewrites/comment.ts
  166. function rewriteCommentNameFromContinuationItems(continuationItems) {
  167. continuationItems.forEach((continuationItem) => {
  168. const { commentThreadRenderer } = continuationItem;
  169. if (commentThreadRenderer !== void 0) {
  170. const { trackingParams } = commentThreadRenderer;
  171. void getCommentElem(trackingParams).then((commentElem) => {
  172. reWriteCommentElem(commentElem, commentThreadRenderer);
  173. });
  174. }
  175. });
  176. }
  177. function reWriteCommentElem(commentElem, commentThreadRenderer) {
  178. const commentRenderer = commentElem.__shady_native_children[0];
  179. if (commentRenderer !== null && commentRenderer !== void 0) {
  180. let isContainer = commentThreadRenderer.comment.commentRenderer.authorIsChannelOwner;
  181. if (commentThreadRenderer.comment.commentRenderer.authorCommentBadge !== void 0) {
  182. isContainer = true;
  183. }
  184. nameRewriteOfCommentRenderer(
  185. commentRenderer,
  186. isContainer,
  187. commentThreadRenderer.comment.commentRenderer.authorEndpoint.browseEndpoint.browseId
  188. );
  189. }
  190. }
  191. async function getCommentElem(trackingParams) {
  192. return await new Promise((resolve) => {
  193. const commentElem = findElementByTrackingParams(
  194. trackingParams,
  195. "#comments > #sections > #contents > ytd-comment-thread-renderer"
  196. );
  197. if (commentElem !== null) {
  198. resolve(commentElem);
  199. } else {
  200. void reSearchElement(trackingParams, "ytd-comment-thread-renderer").then(
  201. (commentElem2) => {
  202. resolve(commentElem2);
  203. }
  204. );
  205. }
  206. });
  207. }
  208.  
  209. // src/rewrites/rewriteOfCommentRenderer/mentionRewriteOfCommentRenderer.ts
  210. function mentionRewriteOfCommentRenderer(commentRenderer) {
  211. const commentRendererBody = commentRenderer.__shady_native_children[2];
  212. const main2 = commentRendererBody.__shady_native_children[1];
  213. const aTags = main2.querySelectorAll(
  214. "#comment-content > ytd-expander > #content > #content-text > a"
  215. );
  216. aTags.forEach((aTag) => {
  217. if (aTag.textContent?.match("@.*") !== null) {
  218. const href = aTag.getAttribute("href");
  219. if (href !== null) {
  220. void getUserName(href.split("/")[2]).then((name) => {
  221. aTag.textContent = \`@\${escapeString(name)} \`;
  222. });
  223. }
  224. }
  225. });
  226. }
  227.  
  228. // src/rewrites/reply.ts
  229. function rewriteReplytNameFromContinuationItems(continuationItems) {
  230. continuationItems.forEach((continuationItem) => {
  231. const { commentRenderer } = continuationItem;
  232. if (commentRenderer !== void 0) {
  233. void getReplyElem(commentRenderer.trackingParams).then((replyElem) => {
  234. reWriteReplyElem(replyElem, commentRenderer);
  235. });
  236. }
  237. });
  238. }
  239. function reWriteReplyElem(replyElem, rendererData) {
  240. let isContainer = rendererData.authorIsChannelOwner;
  241. if (rendererData.authorCommentBadge !== void 0) {
  242. isContainer = true;
  243. }
  244. nameRewriteOfCommentRenderer(
  245. replyElem,
  246. isContainer,
  247. rendererData.authorEndpoint.browseEndpoint.browseId
  248. );
  249. mentionRewriteOfCommentRenderer(replyElem);
  250. }
  251. async function getReplyElem(trackedParams) {
  252. return await new Promise((resolve) => {
  253. const selector = "#replies > ytd-comment-replies-renderer > #expander > #expander-contents > #contents > ytd-comment-renderer";
  254. const commentRenderer = findElementByTrackingParams(
  255. trackedParams,
  256. selector
  257. );
  258. if (commentRenderer !== null) {
  259. resolve(commentRenderer);
  260. } else {
  261. void reSearchElement(trackedParams, selector).then((commentRenderer2) => {
  262. resolve(commentRenderer2);
  263. });
  264. }
  265. });
  266. }
  267. function rewriteTeaserReplytNameFromContinuationItems(continuationItems) {
  268. continuationItems.forEach((continuationItem) => {
  269. const { commentRenderer } = continuationItem;
  270. if (commentRenderer !== void 0) {
  271. void reSearchElementAllByCommentId(
  272. commentRenderer.commentId,
  273. "ytd-comment-replies-renderer > #teaser-replies > ytd-comment-renderer"
  274. ).then((replyElems) => {
  275. replyElems.forEach((replyElem) => {
  276. reWriteReplyElem(replyElem, commentRenderer);
  277. });
  278. });
  279. void reSearchElementAllByCommentId(
  280. commentRenderer.commentId,
  281. "ytd-comment-replies-renderer > #expander > #expander-contents > #contents > ytd-comment-renderer"
  282. ).then((replyElems) => {
  283. replyElems.forEach((replyElem) => {
  284. reWriteReplyElem(replyElem, commentRenderer);
  285. });
  286. });
  287. }
  288. });
  289. }
  290.  
  291. // src/handlers/handleYtAppendContinuationItemsAction.ts
  292. function handleYtAppendContinuationItemsAction(detail) {
  293. const continuationItems = detail.args[0].appendContinuationItemsAction.continuationItems;
  294. if (isCommentRenderer(continuationItems)) {
  295. const replyDetail = detail;
  296. setTimeout(() => {
  297. rewriteReplytNameFromContinuationItems(
  298. replyDetail.args[0].appendContinuationItemsAction.continuationItems
  299. );
  300. }, 1);
  301. } else {
  302. const commentDetail = detail;
  303. setTimeout(() => {
  304. rewriteCommentNameFromContinuationItems(
  305. commentDetail.args[0].appendContinuationItemsAction.continuationItems
  306. );
  307. }, 10);
  308. }
  309. }
  310.  
  311. // src/handlers/handleYtCreateCommentAction.ts
  312. function handleYtCreateCommentAction(detail) {
  313. const createCommentDetail = detail;
  314. const continuationItems = [
  315. {
  316. commentThreadRenderer: createCommentDetail.args[0].createCommentAction.contents.commentThreadRenderer
  317. }
  318. ];
  319. setTimeout(() => {
  320. rewriteCommentNameFromContinuationItems(continuationItems);
  321. }, 100);
  322. }
  323.  
  324. // src/handlers/handleYtCreateCommentReplyAction.ts
  325. function handleYtCreateCommentReplyAction(detail) {
  326. const createReplyDetail = detail;
  327. const continuationItems = [
  328. {
  329. commentRenderer: createReplyDetail.args[0].createCommentReplyAction.contents.commentRenderer
  330. }
  331. ];
  332. setTimeout(() => {
  333. rewriteTeaserReplytNameFromContinuationItems(continuationItems);
  334. }, 100);
  335. }
  336.  
  337. // src/rewrites/highlightedReply.ts
  338. function rewriteHighlightedReply(trackedParams, isContainer, userId) {
  339. const elem = findElementByTrackingParams(
  340. trackedParams,
  341. "ytd-comment-renderer"
  342. );
  343. const rewriteHighlightedReplyElem = (elem2) => {
  344. nameRewriteOfCommentRenderer(elem2, isContainer, userId);
  345. };
  346. if (elem === null) {
  347. void reSearchElement(trackedParams, "ytd-comment-renderer").then((elem2) => {
  348. rewriteHighlightedReplyElem(elem2);
  349. });
  350. } else {
  351. rewriteHighlightedReplyElem(elem);
  352. }
  353. }
  354.  
  355. // src/handlers/handleYtGetMultiPageMenuAction.ts
  356. function handleYtGetMultiPageMenuAction(detail) {
  357. const getMultiPageMenuDetail = detail;
  358. const continuationItems = getMultiPageMenuDetail.args[0].getMultiPageMenuAction.menu.multiPageMenuRenderer.sections[1].itemSectionRenderer?.contents;
  359. const highLightedTeaserContents = getMultiPageMenuDetail.args[0]?.getMultiPageMenuAction?.menu?.multiPageMenuRenderer.sections[1].itemSectionRenderer?.contents[0]?.commentThreadRenderer.replies?.commentRepliesRenderer?.teaserContents;
  360. if (continuationItems !== void 0) {
  361. setTimeout(() => {
  362. rewriteCommentNameFromContinuationItems(continuationItems);
  363. if (highLightedTeaserContents !== void 0) {
  364. const highLightedReplyRenderer = highLightedTeaserContents[0]?.commentRenderer;
  365. let isContainer = highLightedReplyRenderer.authorIsChannelOwner;
  366. if (highLightedReplyRenderer.authorCommentBadge !== void 0) {
  367. isContainer = true;
  368. }
  369. rewriteHighlightedReply(
  370. highLightedReplyRenderer.trackingParams,
  371. isContainer,
  372. highLightedReplyRenderer.authorEndpoint.browseEndpoint.browseId
  373. );
  374. }
  375. }, 100);
  376. }
  377. }
  378.  
  379. // src/handlers/handleYtHistory.ts
  380. function handleYtHistory(detail) {
  381. const historyDetail = detail;
  382. const continuationItems = historyDetail.args[1].historyEntry?.rootData.response.contents.twoColumnWatchNextResults?.results?.results?.contents[3]?.itemSectionRenderer?.contents;
  383. if (continuationItems !== void 0) {
  384. setTimeout(() => {
  385. rewriteCommentNameFromContinuationItems(continuationItems);
  386. }, 100);
  387. }
  388. }
  389.  
  390. // src/handlers/handleYtReloadContinuationItemsCommand.ts
  391. function handleYtReloadContinuationItemsCommand(detail) {
  392. const reloadDetail = detail;
  393. const { slot } = reloadDetail.args[0].reloadContinuationItemsCommand;
  394. if (slot === "RELOAD_CONTINUATION_SLOT_BODY") {
  395. const continuationItems = reloadDetail.args[0].reloadContinuationItemsCommand.continuationItems;
  396. setTimeout(() => {
  397. rewriteCommentNameFromContinuationItems(continuationItems);
  398. }, 100);
  399. }
  400. }
  401.  
  402. // src/index.ts
  403. function main() {
  404. const handleYtAction = (e) => {
  405. const { actionName } = e.detail;
  406. switch (actionName) {
  407. case "yt-append-continuation-items-action":
  408. handleYtAppendContinuationItemsAction(e.detail);
  409. break;
  410. case "yt-reload-continuation-items-command":
  411. handleYtReloadContinuationItemsCommand(e.detail);
  412. break;
  413. case "yt-history-load":
  414. handleYtHistory(e.detail);
  415. break;
  416. case "yt-get-multi-page-menu-action":
  417. handleYtGetMultiPageMenuAction(e.detail);
  418. break;
  419. case "yt-create-comment-action":
  420. handleYtCreateCommentAction(e.detail);
  421. break;
  422. case "yt-create-comment-reply-action":
  423. handleYtCreateCommentReplyAction(e.detail);
  424. break;
  425. }
  426. };
  427. document.addEventListener("yt-action", handleYtAction);
  428. document.addEventListener("yt-navigate-finish", ({ detail }) => {
  429. document.removeEventListener("yt-action", handleYtAction);
  430. document.addEventListener("yt-action", handleYtAction);
  431. });
  432. }
  433.  
  434. // node_modules/ts-extension-builder/tmp/entry.ts
  435. var args = {};
  436. if (typeof GM_info !== "undefined" && GM_info.script.grant !== void 0) {
  437. GM_info.script.grant.forEach((propatyName) => {
  438. let keyName = propatyName.split("GM_")[1];
  439. if (keyName === "xmlhttpRequest") {
  440. keyName = "xmlHttpRequest";
  441. }
  442. args[propatyName] = GM[keyName];
  443. });
  444. }
  445. main(args);
  446. `;
  447. const script = document.createElement("script");
  448. script.innerHTML = scriptString
  449. unsafeWindow.document.body.appendChild(script)

QingJ © 2025

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