- open
chrome://extensions/
and turn on "Developer Mode" on the top right - install tampermonkey:
https://chromewebstore.google.com/detail/tampermonkey/dhdgffkkebhmkfjojejmpbldmpobfkfo
- click on the extension, then click "create a new script"
- in the editor, copy the userscript.js file contents
- install python, flask, and run server.py
Last active
October 18, 2024 19:05
-
-
Save danthemango/0fa0a5f9fd0b3b79059a26f67155317b to your computer and use it in GitHub Desktop.
Detect and send message to your program on Duolingo challenge completed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from flask import Flask, request, jsonify | |
app = Flask(__name__) | |
@app.route('/data', methods=['POST']) | |
def receive_data(): | |
# Get the JSON data sent from Tampermonkey | |
data = request.get_json() | |
print(f"Received data: {data}") | |
# Do something with the data, e.g., save it, process it, etc. | |
# Return a response back to Tampermonkey | |
return jsonify({"message": "Data received successfully", "received": data}) | |
if __name__ == "__main__": | |
app.run(host="0.0.0.0", port=5000) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name Duolingo Lesson Completion Detection | |
// @namespace http://tampermonkey.net/ | |
// @version 0.1 | |
// @description Detect Duolingo lesson completion by intercepting requests and checking body content | |
// @author Daniel Guenther | |
// @match https://www.duolingo.com/learn | |
// @grant GM_xmlhttpRequest | |
// @connect localhost | |
// @run-at document-idle | |
// ==/UserScript== | |
(function() { | |
'use strict'; | |
console.log('lesson completed detector running...'); | |
// Save the original XMLHttpRequest open and send methods | |
const originalXhrOpen = window.XMLHttpRequest.prototype.open; | |
const originalXhrSend = window.XMLHttpRequest.prototype.send; | |
// Override the open method to inspect request details | |
window.XMLHttpRequest.prototype.open = function(method, url) { | |
this._url = url; // Save the request URL for later use | |
originalXhrOpen.apply(this, arguments); // Call the original open method | |
}; | |
// Override the send method to inspect the request body | |
window.XMLHttpRequest.prototype.send = function(body) { | |
if (this._url.includes('https://excess.duolingo.com/challenge_response/batch')) { // Check if this is the challenge response request | |
console.log("Intercepted XHR request to Duolingo challenge_response API!"); | |
// Parse the request body (assuming it's JSON format) | |
const requestBody = JSON.parse(body); | |
// Check for the conditions `correct: true` and `skipped: false` | |
const challengeCompleted = requestBody.some(entry => entry.correct === true && entry.skipped === false); | |
if (challengeCompleted) { | |
console.log("Duolingo challenge completed successfully! Sending signal to server..."); | |
sendChallengeCompleted(); | |
} | |
} | |
// Call the original send method | |
originalXhrSend.apply(this, arguments); | |
}; | |
// Function to send data to the server when a lesson is completed | |
function sendChallengeCompleted() { | |
GM_xmlhttpRequest({ | |
method: "POST", | |
url: "http://localhost:5000/data", // Your server endpoint | |
data: JSON.stringify({ | |
message: "Challeneg completed!", | |
timestamp: new Date().toISOString() | |
}), | |
headers: { | |
"Content-Type": "application/json" | |
}, | |
onload: function(response) { | |
console.log("Response from server:", response.responseText); | |
}, | |
onerror: function(error) { | |
console.error("Error:", error); | |
} | |
}); | |
} | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Partly generated with chatGPT, tested locally on 2024-10-18