Campus Quiz Auto-Answer

Automatically answers quiz questions using AI

Size

10.0 KB

Version

1.1.1

Created

Feb 28, 2026

Updated

21 days ago

1// ==UserScript==
2// @name		Campus Quiz Auto-Answer
3// @description		Automatically answers quiz questions using AI
4// @version		1.1.1
5// @match		https://*.campus.castellsimmerscom.com/*
6// @icon		https://campus.castellsimmerscom.com/pluginfile.php/1/theme_remui/faviconurl/1771165145/favicon-128%20%283%29.png
7// @grant		GM.xmlhttpRequest
8// ==/UserScript==
9(function() {
10    'use strict';
11
12    console.log('Campus Quiz Auto-Answer extension loaded');
13
14    // Debounce function to prevent excessive calls
15    function debounce(func, wait) {
16        let timeout;
17        return function executedFunction(...args) {
18            const later = () => {
19                clearTimeout(timeout);
20                func(...args);
21            };
22            clearTimeout(timeout);
23            timeout = setTimeout(later, wait);
24        };
25    }
26
27    // Function to extract question text from a question element
28    function extractQuestionText(questionElement) {
29        const qtextDiv = questionElement.querySelector('.qtext');
30        if (!qtextDiv) return '';
31        
32        // Get the full text including the blank space context
33        let fullText = qtextDiv.textContent.trim();
34        
35        // Remove "Answer Question X" labels
36        fullText = fullText.replace(/Answer Question \d+/g, '').trim();
37        
38        return fullText;
39    }
40
41    // Function to get all questions on the page
42    function getAllQuestions() {
43        const questions = [];
44        const questionElements = document.querySelectorAll('div.que[id^="question-"]');
45        
46        console.log(`Found ${questionElements.length} questions on the page`);
47        
48        questionElements.forEach((element, index) => {
49            const questionText = extractQuestionText(element);
50            const inputField = element.querySelector('input[type="text"][name*="_answer"]');
51            
52            if (questionText && inputField) {
53                questions.push({
54                    element: element,
55                    text: questionText,
56                    inputField: inputField,
57                    questionNumber: index + 1
58                });
59                console.log(`Question ${index + 1}: ${questionText}`);
60            }
61        });
62        
63        return questions;
64    }
65
66    // Function to use AI to answer a question
67    async function getAIAnswer(questionText) {
68        try {
69            console.log(`Getting AI answer for: ${questionText}`);
70            
71            const prompt = `You are helping a student complete an English grammar quiz. 
72The question is a fill-in-the-blank question. Analyze the sentence and provide ONLY the missing word or phrase that completes the sentence correctly.
73
74Question: ${questionText}
75
76Provide ONLY the word or short phrase that fills in the blank. Do not include any explanation, punctuation, or additional text. Just the answer word(s).`;
77
78            const answer = await RM.aiCall(prompt, {
79                type: 'json_schema',
80                json_schema: {
81                    name: 'quiz_answer',
82                    schema: {
83                        type: 'object',
84                        properties: {
85                            answer: { 
86                                type: 'string',
87                                description: 'The word or phrase that fills in the blank'
88                            },
89                            confidence: {
90                                type: 'string',
91                                enum: ['high', 'medium', 'low'],
92                                description: 'Confidence level in the answer'
93                            }
94                        },
95                        required: ['answer', 'confidence']
96                    }
97                }
98            });
99            
100            console.log(`AI Answer: ${answer.answer} (Confidence: ${answer.confidence})`);
101            return answer.answer;
102            
103        } catch (error) {
104            console.error('Error getting AI answer:', error);
105            return null;
106        }
107    }
108
109    // Function to fill in an answer
110    function fillAnswer(inputField, answer) {
111        if (!inputField || !answer) return false;
112        
113        inputField.value = answer;
114        inputField.dispatchEvent(new Event('input', { bubbles: true }));
115        inputField.dispatchEvent(new Event('change', { bubbles: true }));
116        
117        return true;
118    }
119
120    // Main function to auto-answer all questions
121    async function autoAnswerQuestions() {
122        const button = document.getElementById('auto-answer-btn');
123        if (button) {
124            button.disabled = true;
125            button.textContent = 'Processing...';
126            button.style.backgroundColor = '#ffc107';
127        }
128        
129        console.log('Starting auto-answer process...');
130        
131        const questions = getAllQuestions();
132        
133        if (questions.length === 0) {
134            alert('No questions found on this page!');
135            if (button) {
136                button.disabled = false;
137                button.textContent = 'šŸ¤– Auto Answer Quiz';
138                button.style.backgroundColor = '#28a745';
139            }
140            return;
141        }
142        
143        let successCount = 0;
144        let failCount = 0;
145        
146        for (const question of questions) {
147            try {
148                // Show progress
149                if (button) {
150                    button.textContent = `Processing ${question.questionNumber}/${questions.length}...`;
151                }
152                
153                const answer = await getAIAnswer(question.text);
154                
155                if (answer) {
156                    const filled = fillAnswer(question.inputField, answer);
157                    if (filled) {
158                        successCount++;
159                        console.log(`āœ“ Question ${question.questionNumber} answered: ${answer}`);
160                        
161                        // Visual feedback - highlight the filled input
162                        question.inputField.style.backgroundColor = '#d4edda';
163                        question.inputField.style.border = '2px solid #28a745';
164                    } else {
165                        failCount++;
166                        console.error(`āœ— Failed to fill answer for question ${question.questionNumber}`);
167                    }
168                } else {
169                    failCount++;
170                    console.error(`āœ— No answer received for question ${question.questionNumber}`);
171                }
172                
173                // Small delay between questions to avoid overwhelming the AI
174                await new Promise(resolve => setTimeout(resolve, 500));
175                
176            } catch (error) {
177                failCount++;
178                console.error(`Error processing question ${question.questionNumber}:`, error);
179            }
180        }
181        
182        // Show completion message
183        const message = `Auto-answer complete!\nāœ“ Answered: ${successCount}\nāœ— Failed: ${failCount}`;
184        console.log(message);
185        alert(message);
186        
187        if (button) {
188            button.disabled = false;
189            button.textContent = 'šŸ¤– Auto Answer Quiz';
190            button.style.backgroundColor = '#28a745';
191        }
192    }
193
194    // Function to create and add the auto-answer button
195    function createAutoAnswerButton() {
196        // Check if we're on a quiz attempt page
197        if (!window.location.href.includes('/mod/quiz/attempt.php')) {
198            console.log('Not on a quiz attempt page, skipping button creation');
199            return;
200        }
201        
202        // Check if button already exists
203        if (document.getElementById('auto-answer-btn')) {
204            console.log('Auto-answer button already exists');
205            return;
206        }
207        
208        // Find the submit button container
209        const submitContainer = document.querySelector('.submitbtns');
210        if (!submitContainer) {
211            console.log('Submit button container not found, will retry...');
212            return;
213        }
214        
215        // Create the auto-answer button
216        const autoAnswerBtn = document.createElement('button');
217        autoAnswerBtn.id = 'auto-answer-btn';
218        autoAnswerBtn.type = 'button';
219        autoAnswerBtn.textContent = 'šŸ¤– Auto Answer Quiz';
220        autoAnswerBtn.className = 'btn btn-success';
221        autoAnswerBtn.style.cssText = `
222            background-color: #28a745;
223            color: white;
224            border: none;
225            padding: 10px 20px;
226            font-size: 16px;
227            font-weight: bold;
228            border-radius: 4px;
229            cursor: pointer;
230            margin-right: 10px;
231            transition: background-color 0.3s;
232        `;
233        
234        autoAnswerBtn.addEventListener('mouseover', () => {
235            if (!autoAnswerBtn.disabled) {
236                autoAnswerBtn.style.backgroundColor = '#218838';
237            }
238        });
239        
240        autoAnswerBtn.addEventListener('mouseout', () => {
241            if (!autoAnswerBtn.disabled) {
242                autoAnswerBtn.style.backgroundColor = '#28a745';
243            }
244        });
245        
246        autoAnswerBtn.addEventListener('click', autoAnswerQuestions);
247        
248        // Insert the button before the submit button
249        submitContainer.insertBefore(autoAnswerBtn, submitContainer.firstChild);
250        
251        console.log('Auto-answer button created successfully');
252    }
253
254    // Initialize the extension
255    function init() {
256        console.log('Initializing Campus Quiz Auto-Answer extension...');
257        
258        // Wait for the page to be fully loaded
259        if (document.readyState === 'loading') {
260            document.addEventListener('DOMContentLoaded', init);
261            return;
262        }
263        
264        // Create the button after a short delay to ensure DOM is ready
265        setTimeout(createAutoAnswerButton, 1000);
266        
267        // Also observe for dynamic content changes
268        const observer = new MutationObserver(debounce(() => {
269            createAutoAnswerButton();
270        }, 1000));
271        
272        observer.observe(document.body, {
273            childList: true,
274            subtree: true
275        });
276    }
277
278    // Start the extension
279    init();
280
281})();