return-youtube-dislike.background.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. const apiUrl = "https://returnyoutubedislikeapi.com";
  2. browser.runtime.onMessage.addListener((request, sender, sendResponse) => {
  3. if (request.message === "get_auth_token") {
  4. // chrome.identity.getAuthToken({ interactive: true }, function (token) {
  5. // console.log(token);
  6. // chrome.identity.getProfileUserInfo(function (userInfo) {
  7. // console.log(JSON.stringify(userInfo));
  8. // });
  9. // });
  10. } else if (request.message === "log_off") {
  11. // console.log("logging off");
  12. // chrome.identity.clearAllCachedAuthTokens(() => console.log("logged off"));
  13. } else if (request.message == "set_state") {
  14. console.log(request);
  15. // chrome.identity.getAuthToken({ interactive: true }, function (token) {
  16. let token = "";
  17. fetch(`${apiUrl}/votes?videoId=${request.videoId}`, {
  18. method: "GET",
  19. headers: {
  20. Accept: "application/json",
  21. Authorization: "Bearer " + token,
  22. },
  23. })
  24. .then((response) => response.json())
  25. .then((response) => {
  26. console.log(response);
  27. sendResponse(response);
  28. })
  29. .catch();
  30. //});
  31. return true;
  32. } else if (request.message == "send_links") {
  33. toSend = toSend.concat(request.videoIds.filter((x) => !sentIds.has(x)));
  34. if (toSend.length >= 20) {
  35. fetch(`${apiUrl}/votes`, {
  36. method: "POST",
  37. headers: {
  38. "Content-Type": "application/json",
  39. },
  40. body: JSON.stringify(toSend),
  41. });
  42. for (const toSendUrl of toSend) {
  43. sentIds.add(toSendUrl);
  44. }
  45. toSend = [];
  46. }
  47. } else if (request.message == "fetch_from_youtube") {
  48. let headers = {}
  49. if (navigator && navigator.userAgent) {
  50. // Never request mobile version
  51. headers["User-Agent"] = navigator.userAgent.replace(/\(.*Mobile;/,"(X11; Linux x86_64;");
  52. }
  53. fetch(`https://www.youtube.com/watch?v=${request.videoId}`, {
  54. method: "GET",
  55. headers: headers
  56. })
  57. .then((response) => response.text())
  58. .then((text) => {
  59. let result = getDislikesFromYoutubeResponse(text);
  60. sendResponse(result);
  61. try {
  62. sendUserSubmittedStatisticsToApi({
  63. ...result,
  64. videoId: request.videoId,
  65. });
  66. } catch {}
  67. });
  68. return true;
  69. }
  70. });
  71. const sentIds = new Set();
  72. let toSend = [];
  73. let lastCalled = new Date();
  74. browser.tabs.onUpdated.addListener(async (tabId, changeInfo, tab) => {
  75. if (changeInfo.status == "complete" && new Date() - lastCalled > 100) {
  76. lastCalled = new Date();
  77. console.log("Tab update complete");
  78. if (tab.url && tab.url.indexOf("youtube.") < 0) return;
  79. browser.tabs.get(tabId, (tab) => {
  80. browser.tabs.executeScript(tab.id, {
  81. file: "return-youtube-dislike.script.js",
  82. });
  83. });
  84. }
  85. });
  86. function getDislikesFromYoutubeResponse(htmlResponse) {
  87. let start =
  88. htmlResponse.indexOf('"videoDetails":') + '"videoDetails":'.length;
  89. let end =
  90. htmlResponse.indexOf('"isLiveContent":false}', start) +
  91. '"isLiveContent":false}'.length;
  92. if (end < start) {
  93. end =
  94. htmlResponse.indexOf('"isLiveContent":true}', start) +
  95. '"isLiveContent":true}'.length;
  96. }
  97. let jsonStr = htmlResponse.substring(start, end);
  98. let jsonResult = JSON.parse(jsonStr);
  99. let rating = jsonResult.averageRating;
  100. start = htmlResponse.indexOf('"topLevelButtons":[', end);
  101. start =
  102. htmlResponse.indexOf('"accessibilityData":', start) +
  103. '"accessibilityData":'.length;
  104. end = htmlResponse.indexOf("}", start);
  105. let likes = +htmlResponse.substring(start, end).replace(/\D/g, "");
  106. let dislikes = (likes * (5 - rating)) / (rating - 1);
  107. let result = {
  108. likes,
  109. dislikes: Math.round(dislikes),
  110. rating,
  111. viewCount: +jsonResult.viewCount,
  112. };
  113. return result;
  114. }
  115. function sendUserSubmittedStatisticsToApi(statistics) {
  116. fetch(`${apiUrl}/votes/user-submitted`, {
  117. method: "POST",
  118. headers: {
  119. "Content-Type": "application/json",
  120. },
  121. body: JSON.stringify(statistics),
  122. });
  123. }