Quill.org Cheat

Get answers for Quill.org

  1. // ==UserScript==
  2. // @name Quill.org Cheat
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.2
  5. // @description Get answers for Quill.org
  6. // @author Caden Finkelstein
  7. // @match https://www.quill.org/connect/*
  8. // @grant none
  9. // ==/UserScript==
  10.  
  11. (function () {
  12. "use strict";
  13.  
  14. // Function to clear existing content
  15. function clearContent() {
  16. const contentDiv = document.querySelector("main");
  17. const styles = document.createElement("style");
  18. styles.innerText = `
  19. .questions {
  20. color: red;
  21. background: black;
  22. z-index: 99;
  23. position: absolute;
  24. }
  25. `
  26. document.body.appendChild(styles);
  27. if (contentDiv) {
  28. console.log("Content container found.");
  29. } else {
  30. console.error("Content container not found.");
  31. }
  32. }
  33.  
  34. // Function to get URL parameters
  35. function getUrlParams(url) {
  36. const match = url.match(/\/lesson\/([^?#/]+)/);
  37. if (match) {
  38. const id = match[1];
  39. return { id };
  40. }
  41. return { id: null }; // Return null if ID is not found
  42. }
  43.  
  44. // Function to display questions and answers
  45. function displayQuestionsAndAnswers(questions, responses) {
  46. const contentDiv = document.querySelector("main");
  47. if (contentDiv) {
  48. questions.forEach((question, index) => {
  49. const questionDiv = document.createElement("div");
  50. questionDiv.className = "question";
  51. questionDiv.textContent = `Question: ${question.key}`;
  52. contentDiv.appendChild(questionDiv);
  53.  
  54. const responseDiv = document.createElement("div");
  55. responseDiv.className="answer";
  56. responseDiv.textContent = `Response: ${responses[index]}`;
  57. contentDiv.appendChild(responseDiv);
  58.  
  59. const separator = document.createElement("hr");
  60. contentDiv.appendChild(separator);
  61. });
  62. } else {
  63. console.error("Content container not found.");
  64. }
  65. }
  66.  
  67. // Function to fetch responses for questions
  68. async function fetchResponses(questions) {
  69. const responses = [];
  70. for (const question of questions) {
  71. const questionId = question.key;
  72. try {
  73. const responseUrl = `https://cms.quill.org/questions/${questionId}/responses`;
  74. const response = await fetch(responseUrl);
  75. const responseData = await response.json();
  76.  
  77. // Check if responseData is an array of objects
  78. if (
  79. Array.isArray(responseData) &&
  80. responseData.length > 0 &&
  81. typeof responseData[0] === "object"
  82. ) {
  83. // Extract relevant information from each object and concatenate into a string
  84. // const responseText = responseData.map((obj) => obj.text).join(", ");
  85. // responses.push(responseText);
  86. responses.push(responseData[0].text);
  87. } else {
  88. console.error(
  89. `Invalid response data format for question ${questionId}`
  90. );
  91. responses.push("Error fetching response");
  92. }
  93. } catch (error) {
  94. console.error(
  95. `Error fetching responses for question ${questionId}:`,
  96. error
  97. );
  98. responses.push("Error fetching response");
  99. }
  100. }
  101. return responses;
  102. }
  103.  
  104. // Function to start the script
  105. async function start() {
  106. clearContent(); // Clear existing content
  107. const currentUrl = window.location.href;
  108. const { id } = getUrlParams(currentUrl);
  109. const jsonUrl = `https://www.quill.org/api/v1/lessons/${id}.json`;
  110.  
  111. try {
  112. const response = await fetch(jsonUrl);
  113. const jsonData = await response.json();
  114. const questions = jsonData.questions;
  115.  
  116. const responses = await fetchResponses(questions);
  117. displayQuestionsAndAnswers(questions, responses);
  118. } catch (error) {
  119. console.error("Error fetching JSON data:", error);
  120. }
  121. }
  122.  
  123. // Function to initialize the script
  124. function initialize() {
  125. const quillButton = document.querySelector(".quill-button");
  126. if (quillButton) {
  127. quillButton.addEventListener("click", start);
  128. } else {
  129. console.error("Quill button not found, waiting for it to appear.");
  130. waitForQuillButton();
  131. }
  132. }
  133.  
  134. // Function to wait for the Quill button
  135. function waitForQuillButton() {
  136. const observer = new MutationObserver((mutations) => {
  137. mutations.forEach((mutation) => {
  138. const quillButton = document.querySelector(".quill-button");
  139. if (quillButton) {
  140. observer.disconnect();
  141. quillButton.addEventListener("click", start);
  142. console.log("Quill button found and event listener attached.");
  143. }
  144. });
  145. });
  146.  
  147. observer.observe(document.body, { childList: true, subtree: true });
  148. }
  149.  
  150. // Call the initialize function
  151. initialize();
  152. })();