Size
4.9 KB
Version
1.0.1
Created
Jan 21, 2026
Updated
13 days ago
1// ==UserScript==
2// @name IXL Auto Answer
3// @description Automatically answers IXL questions correctly using AI
4// @version 1.0.1
5// @match https://*.ixl.com/*
6// @icon https://www.ixl.com/ixl-favicon.png
7// ==/UserScript==
8(function() {
9 'use strict';
10
11 console.log('IXL Auto Answer extension loaded');
12
13 // Debounce function to prevent excessive calls
14 function debounce(func, wait) {
15 let timeout;
16 return function executedFunction(...args) {
17 const later = () => {
18 clearTimeout(timeout);
19 func(...args);
20 };
21 clearTimeout(timeout);
22 timeout = setTimeout(later, wait);
23 };
24 }
25
26 // Function to extract question text
27 function getQuestionText() {
28 const questionElement = document.querySelector('.ela.section .rich-text .instructions');
29 if (questionElement) {
30 return questionElement.textContent.trim();
31 }
32 return null;
33 }
34
35 // Function to get all answer options
36 function getAnswerOptions() {
37 const options = [];
38 const tiles = document.querySelectorAll('.SelectableTile[role="radio"]');
39
40 tiles.forEach((tile, index) => {
41 const textElement = tile.querySelector('.rich-text');
42 if (textElement) {
43 options.push({
44 index: index,
45 text: textElement.textContent.trim(),
46 element: tile
47 });
48 }
49 });
50
51 return options;
52 }
53
54 // Function to select an answer
55 function selectAnswer(answerElement) {
56 console.log('Selecting answer:', answerElement.textContent.trim());
57 answerElement.click();
58 }
59
60 // Function to submit the answer
61 function submitAnswer() {
62 const submitButton = document.querySelector('.yui3-widget-ft button.crisp-button');
63 if (submitButton && submitButton.textContent.includes('Submit')) {
64 console.log('Submitting answer...');
65 setTimeout(() => {
66 submitButton.click();
67 }, 500);
68 }
69 }
70
71 // Main function to answer the question
72 async function answerQuestion() {
73 try {
74 const questionText = getQuestionText();
75 const answerOptions = getAnswerOptions();
76
77 if (!questionText || answerOptions.length === 0) {
78 console.log('Question or answers not found yet');
79 return;
80 }
81
82 console.log('Question:', questionText);
83 console.log('Answer options:', answerOptions.map(opt => opt.text));
84
85 // Create prompt for AI
86 const optionsText = answerOptions.map((opt, idx) => `${idx + 1}. ${opt.text}`).join('\n');
87 const prompt = `Question: ${questionText}\n\nAnswer options:\n${optionsText}\n\nWhich answer is correct? Respond with only the number (1, 2, 3, etc.) of the correct answer.`;
88
89 console.log('Asking AI for the correct answer...');
90
91 // Call AI to get the correct answer
92 const aiResponse = await RM.aiCall(prompt);
93 console.log('AI response:', aiResponse);
94
95 // Parse the AI response to get the answer index
96 const answerNumber = parseInt(aiResponse.trim());
97
98 if (isNaN(answerNumber) || answerNumber < 1 || answerNumber > answerOptions.length) {
99 console.error('Invalid AI response:', aiResponse);
100 return;
101 }
102
103 const correctAnswer = answerOptions[answerNumber - 1];
104 console.log('Correct answer:', correctAnswer.text);
105
106 // Select the correct answer
107 selectAnswer(correctAnswer.element);
108
109 // Submit the answer
110 submitAnswer();
111
112 } catch (error) {
113 console.error('Error answering question:', error);
114 }
115 }
116
117 // Observe DOM changes to detect new questions
118 function observeQuestions() {
119 const observer = new MutationObserver(debounce(() => {
120 console.log('DOM changed, checking for questions...');
121 answerQuestion();
122 }, 1000));
123
124 observer.observe(document.body, {
125 childList: true,
126 subtree: true
127 });
128
129 console.log('Started observing for questions');
130 }
131
132 // Initialize the extension
133 function init() {
134 console.log('Initializing IXL Auto Answer...');
135
136 // Wait for page to load
137 if (document.readyState === 'loading') {
138 document.addEventListener('DOMContentLoaded', () => {
139 setTimeout(() => {
140 answerQuestion();
141 observeQuestions();
142 }, 2000);
143 });
144 } else {
145 setTimeout(() => {
146 answerQuestion();
147 observeQuestions();
148 }, 2000);
149 }
150 }
151
152 init();
153})();