Quillbot Premium Unlocker

Unlocks Quillbot Premium features with improved stability and compatibility

  1. // ==UserScript==
  2. // @name Quillbot Premium Unlocker
  3. // @namespace quillbot.taozhiyu.gitee.io
  4. // @version 1.0.0
  5. // @description Unlocks Quillbot Premium features with improved stability and compatibility
  6. // @author longkidkoolstar
  7. // @match https://quillbot.com/*
  8. // @icon https://quillbot.com/favicon.png
  9. // @require https://greatest.deepsurf.us/scripts/455943-ajaxhooker/code/ajaxHooker.js?version=1124435
  10. // @run-at document-start
  11. // @grant GM_setValue
  12. // @grant GM_getValue
  13. // @license none
  14. // ==/UserScript==
  15. /* global ajaxHooker*/
  16. (function() {
  17. 'use strict';
  18.  
  19. // Configuration
  20. const CONFIG = {
  21. debug: false, // Enable for additional console logging
  22. notificationDuration: 5000, // How long to show status notifications (ms)
  23. theme: {
  24. primary: "#4CAF50", // Primary color - green
  25. text: "#333333",
  26. background: "#f9f9f9",
  27. shadow: "0 2px 5px rgba(0, 0, 0, 0.1)"
  28. },
  29. premiumFeatures: [
  30. "Word Count Limit",
  31. "Premium Modes",
  32. "Grammar Checker",
  33. "Premium Synonyms",
  34. "Sentence Rephraser"
  35. ]
  36. };
  37.  
  38. // Logger utility
  39. const logger = {
  40. log: (message) => CONFIG.debug && console.log(`[QuillbotUnlocker] ${message}`),
  41. success: (message) => CONFIG.debug && console.log(`[QuillbotUnlocker] %c${message}`, "color: green"),
  42. error: (message, err) => CONFIG.debug && console.error(`[QuillbotUnlocker] ${message}`, err)
  43. };
  44.  
  45. // Enhanced API interceptor module
  46. const apiInterceptor = {
  47. init: () => {
  48. try {
  49. ajaxHooker.hook((request) => {
  50. // Account details endpoint (main premium flag)
  51. if (request.url.endsWith("get-account-details")) {
  52. logger.log("Intercepting account details request");
  53.  
  54. request.response = (response) => {
  55. try {
  56. const responseData = JSON.parse(response.responseText);
  57. const accountData = "data" in responseData ? responseData.data : responseData;
  58.  
  59. // Set premium status flags
  60. accountData.profile.accepted_premium_modes_tnc = true;
  61. accountData.profile.premium = true;
  62. accountData.profile.client_type = "premium";
  63. accountData.profile.premium_tier = "premium_plus";
  64.  
  65. // Enhanced word limits
  66. if (accountData.limits) {
  67. const enhancedLimits = {
  68. limit: 250000,
  69. premium_limit: 250000,
  70. used: 0,
  71. };
  72.  
  73. // Apply to all limit types
  74. accountData.limits.paraphrase = { ...accountData.limits.paraphrase, ...enhancedLimits };
  75. accountData.limits.grammar = { ...accountData.limits.grammar, ...enhancedLimits };
  76. accountData.limits.cowrite = { ...(accountData.limits.cowrite || {}), ...enhancedLimits };
  77. accountData.limits.summarizer = { ...(accountData.limits.summarizer || {}), ...enhancedLimits };
  78. }
  79.  
  80. // Unlock subscription features
  81. if (accountData.user) {
  82. accountData.user.subscription = {
  83. type: "premium_plus",
  84. status: "active",
  85. };
  86. }
  87.  
  88. // Update response with modified data
  89. response.responseText = JSON.stringify(
  90. "data" in responseData ? ((responseData.data = accountData), responseData) : accountData
  91. );
  92.  
  93. logger.success("Premium status enabled successfully");
  94. uiManager.showStatusNotification("Premium features unlocked successfully!");
  95. } catch (err) {
  96. logger.error("Error processing account details response", err);
  97. uiManager.showStatusNotification("Error unlocking premium features");
  98. }
  99. };
  100. }
  101.  
  102. // Additional endpoints for premium features
  103. if (
  104. request.url.includes("/billing/") ||
  105. request.url.includes("/subscription/") ||
  106. request.url.includes("/premium-access")
  107. ) {
  108. logger.log("Intercepting premium endpoint request");
  109.  
  110. request.response = (response) => {
  111. try {
  112. // Return a successful premium status
  113. response.responseText = JSON.stringify({
  114. success: true,
  115. data: {
  116. has_premium_access: true,
  117. status: "active",
  118. tier: "premium_plus",
  119. },
  120. });
  121. logger.success("Premium access granted successfully");
  122. } catch (err) {
  123. logger.error("Error processing premium endpoint response", err);
  124. }
  125. };
  126. }
  127. });
  128. logger.success("API interceptors initialized");
  129. } catch (err) {
  130. logger.error("Failed to initialize API interceptors", err);
  131. uiManager.showStatusNotification("Failed to initialize premium unlocker");
  132. }
  133. }
  134. };
  135.  
  136. // UI Manager with minimal interface
  137. const uiManager = {
  138. // Lightweight status notification
  139. showStatusNotification: (message) => {
  140. if (document.body) {
  141. const notification = document.createElement("div");
  142. notification.style.position = "fixed";
  143. notification.style.bottom = "20px";
  144. notification.style.right = "20px";
  145. notification.style.padding = "10px 15px";
  146. notification.style.backgroundColor = CONFIG.theme.background;
  147. notification.style.color = CONFIG.theme.text;
  148. notification.style.border = "1px solid #ccc";
  149. notification.style.borderLeft = `4px solid ${CONFIG.theme.primary}`;
  150. notification.style.borderRadius = "4px";
  151. notification.style.boxShadow = CONFIG.theme.shadow;
  152. notification.style.fontFamily = "Arial, sans-serif";
  153. notification.style.fontSize = "14px";
  154. notification.style.zIndex = "10000";
  155.  
  156. notification.textContent = message;
  157.  
  158. document.body.appendChild(notification);
  159.  
  160. // Remove after duration
  161. setTimeout(() => {
  162. if (notification.parentNode) {
  163. notification.parentNode.removeChild(notification);
  164. }
  165. }, CONFIG.notificationDuration);
  166. }
  167. },
  168.  
  169. // Simple info popup
  170. showInfoPopup: () => {
  171. const popup = document.createElement("div");
  172. popup.style.position = "fixed";
  173. popup.style.bottom = "20px";
  174. popup.style.right = "20px";
  175. popup.style.padding = "15px";
  176. popup.style.backgroundColor = CONFIG.theme.background;
  177. popup.style.boxShadow = CONFIG.theme.shadow;
  178. popup.style.border = "1px solid #ccc";
  179. popup.style.borderRadius = "8px";
  180. popup.style.zIndex = "10000";
  181. popup.style.fontFamily = "Arial, sans-serif";
  182. popup.style.color = CONFIG.theme.text;
  183. popup.style.width = "280px";
  184.  
  185. // Add header
  186. const header = document.createElement("h3");
  187. header.textContent = "Quillbot Premium Unlocker";
  188. header.style.margin = "0 0 10px";
  189. header.style.color = CONFIG.theme.primary;
  190. header.style.fontSize = "16px";
  191.  
  192. // Add features list
  193. const featuresHeader = document.createElement("p");
  194. featuresHeader.textContent = "Unlocked features:";
  195. featuresHeader.style.margin = "10px 0 5px";
  196. featuresHeader.style.fontWeight = "bold";
  197.  
  198. const featuresList = document.createElement("ul");
  199. featuresList.style.margin = "0 0 15px";
  200. featuresList.style.paddingLeft = "20px";
  201.  
  202. CONFIG.premiumFeatures.forEach(feature => {
  203. const item = document.createElement("li");
  204. item.textContent = feature;
  205. item.style.margin = "3px 0";
  206. featuresList.appendChild(item);
  207. });
  208.  
  209. // Add Discord link
  210. const communityMsg = document.createElement("p");
  211. communityMsg.textContent = "Join our Discord community for support and additional resources:";
  212. communityMsg.style.margin = "10px 0 5px";
  213. communityMsg.style.fontSize = "13px";
  214.  
  215. const link = document.createElement("a");
  216. link.href = "https://discord.gg/JrweGzdjwA";
  217. link.textContent = "Join Discord";
  218. link.style.color = "#0366d6";
  219. link.style.textDecoration = "none";
  220. link.target = "_blank";
  221. link.style.display = "inline-block";
  222. link.style.marginTop = "5px";
  223.  
  224. // Add close button
  225. const closeButton = document.createElement("button");
  226. closeButton.textContent = "×";
  227. closeButton.style.position = "absolute";
  228. closeButton.style.top = "5px";
  229. closeButton.style.right = "5px";
  230. closeButton.style.background = "none";
  231. closeButton.style.border = "none";
  232. closeButton.style.cursor = "pointer";
  233. closeButton.style.fontSize = "18px";
  234. closeButton.style.color = "#666";
  235.  
  236. closeButton.addEventListener("click", () => {
  237. if (popup.parentNode) {
  238. document.body.removeChild(popup);
  239. }
  240. });
  241.  
  242. // Assemble elements
  243. popup.appendChild(header);
  244. popup.appendChild(featuresHeader);
  245. popup.appendChild(featuresList);
  246. popup.appendChild(communityMsg);
  247. popup.appendChild(link);
  248. popup.appendChild(closeButton);
  249.  
  250. document.body.appendChild(popup);
  251.  
  252. // Auto-close after 15 seconds
  253. setTimeout(() => {
  254. if (popup.parentNode) {
  255. document.body.removeChild(popup);
  256. }
  257. }, 15000);
  258. }
  259. };
  260.  
  261. // Initialize the premium unlocker
  262. (function init() {
  263. // Start API interception immediately
  264. apiInterceptor.init();
  265.  
  266. // Show info popup after page loads
  267. window.addEventListener("load", () => {
  268. setTimeout(() => {
  269. uiManager.showInfoPopup();
  270. }, 2000);
  271. });
  272.  
  273. logger.log("Quillbot Premium Unlocker initialized");
  274. })();
  275. })();