Send to Real-Debrid

Add a button next to each magnet link to send it to Real-Debrid, with user-friendly API token setup and enhanced error handling

  1. // ==UserScript==
  2. // @name Send to Real-Debrid
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.2.7
  5. // @description Add a button next to each magnet link to send it to Real-Debrid, with user-friendly API token setup and enhanced error handling
  6. // @author dlee2
  7. // @license MIT
  8. // @match *://*nyaa.si/*
  9. // @match *://*thepiratebay.*
  10. // @match *://*1337x.*
  11. // @match *://*rarbg.*
  12. // @match *://*yts.*
  13. // @match *://*eztv.*
  14. // @match *://*torrentz2.*
  15. // @match *://*zooqle.*
  16. // @match *://*limetorrents.*
  17. // @match *://*kickasstorrents.*
  18. // @match *://*torrentdownloads.*
  19. // @match *://*extratorrent.*
  20. // @match *://*torrentgalaxy.*
  21. // @match *://*magnetdl.*
  22. // @grant GM_xmlhttpRequest
  23. // @grant GM_setValue
  24. // @grant GM_getValue
  25. // ==/UserScript==
  26.  
  27.  
  28. (function () {
  29. 'use strict';
  30.  
  31. function getApiToken() {
  32. let apiToken = GM_getValue('apiToken');
  33. if (!apiToken) {
  34. apiToken = prompt('Enter your Real-Debrid API token:', '');
  35. if (apiToken) {
  36. GM_setValue('apiToken', apiToken);
  37. } else {
  38. alert('No API token provided. Set it later by clicking a "Send to RD" button.');
  39. return null;
  40. }
  41. }
  42. return apiToken;
  43. }
  44.  
  45. function handleApiError(response) {
  46. let errorMsg = 'Error occurred while sending request to Real-Debrid.';
  47. if (response.status === 401) {
  48. errorMsg = 'Invalid or expired API token.';
  49. } else if (response.status === 403) {
  50. errorMsg = 'Permission denied. Account might be locked.';
  51. }
  52. alert(errorMsg);
  53. console.error('Real-Debrid API Error:', response.status, response.responseText);
  54. }
  55.  
  56. function sendToRealDebrid(magnetLink) {
  57. const API_TOKEN = getApiToken();
  58. if (!API_TOKEN) {
  59. return;
  60. }
  61.  
  62. GM_xmlhttpRequest({
  63. method: "POST",
  64. url: "https://api.real-debrid.com/rest/1.0/torrents/addMagnet",
  65. headers: {
  66. "Authorization": `Bearer ${API_TOKEN}`,
  67. "Content-Type": "application/x-www-form-urlencoded"
  68. },
  69. data: "magnet=" + encodeURIComponent(magnetLink),
  70. onload: function (response) {
  71. if (response.status === 201) {
  72. let torrentId = JSON.parse(response.responseText).id;
  73. selectAllFiles(torrentId, API_TOKEN);
  74. } else {
  75. handleApiError(response);
  76. }
  77. },
  78. onerror: function (response) {
  79. handleApiError(response);
  80. }
  81. });
  82. }
  83.  
  84. function selectAllFiles(torrentId, apiToken) {
  85. GM_xmlhttpRequest({
  86. method: "POST",
  87. url: `https://api.real-debrid.com/rest/1.0/torrents/selectFiles/${torrentId}`,
  88. headers: {
  89. "Authorization": `Bearer ${apiToken}`
  90. },
  91. data: "files=all",
  92. onload: function (response) {
  93. if (response.status === 204) {
  94. alert("All files have been selected for download.");
  95. } else {
  96. console.error('Error selecting files:', response.responseText);
  97. alert("Failed to select files for download.");
  98. }
  99. },
  100. onerror: function (response) {
  101. console.error('Error sending request to select files:', response.responseText);
  102. alert("Error occurred while selecting files for download.");
  103. }
  104. });
  105. }
  106.  
  107. function createSendButton(magnetLink) {
  108. let button = document.createElement('button');
  109. button.textContent = 'RD';
  110. button.style.marginLeft = '10px';
  111. button.addEventListener('click', function () {
  112. sendToRealDebrid(magnetLink);
  113. });
  114. return button;
  115. }
  116.  
  117. function addSendButtons() {
  118. let magnetLinks = document.querySelectorAll('a[href^="magnet:"]');
  119. magnetLinks.forEach(link => {
  120. let sendButton = createSendButton(link.href);
  121. link.parentNode.insertBefore(sendButton, link.nextSibling);
  122. });
  123. }
  124.  
  125. addSendButtons();
  126. })();