The script previously worked in this interface:
enter image description here
This is the current page and I got everything out of “validatetoken”
**enter image description here
This is the programming that each script documentation has
- getData.js:
const data = require("./constants.json");
const authorization = data["authorization"];
const languageCode = data["languageCode"];
async function getData() {
const res = await fetch("https://graph.rosettastone.com/graphql", {
credentials: "include",
headers: {
"User-Agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/115.0",
Accept: "*/*",
"Accept-Language": "en-US,en;q=0.5",
"content-type": "application/json",
authorization: authorization,
"x-request-id": "66a4813c-8077-4509-9875-6c10608b9933",
"Sec-Fetch-Dest": "empty",
"Sec-Fetch-Mode": "cors",
"Sec-Fetch-Site": "same-site",
},
referrer: "https://totale.rosettastone.com/",
body:
'{"operationName":"GetCourseMenu","variables":{"languageCode":"' +
languageCode +
'","filter":"ALL","chunking":false,"includeMilestoneInLessonFour":true},"query":"query GetCourseMenu($languageCode: String!, $filter: String!, $includeMilestoneInLessonFour: Boolean!, $chunking: Boolean!) {\n courseMenu(\n languageCode: $languageCode\n includeMilestoneInLessonFour: $includeMilestoneInLessonFour\n chunking: $chunking\n filter: $filter\n ) {
n currentCourseId\n bookmarkToUseOnload {\n course\n bookmarkToUseOnload\n __typename\n }\n speechEnabledBookmark {\n course\n unitIndex\n lessonIndex\n pathType\n __typename\n }\n speechDisabledBookmark {\n course
n unitIndex\n lessonIndex\n pathType\n __typename\n }\n curriculumDefaults {\n course\n curriculumId\n resource\n __typename\n }\n viperDefinedCurricula {\n id\n course\n firstExerciseId\n exerciseCount\n nameByLocale {\n curriculumId\n locale\n curriculumNameLocalized\n __typename\n }\n descriptionByLocale {\n curriculumId\n locale\n curriculumDescriptionLocalized\n __typename\n }\n __typename\n }\n showCurriculumChooser {\n course\n showCurriculumChooser\n __typename\n }\n numberOfUnits\n units {\n id\n index\n unitNumber\n titleKey\n color\n colorDesaturated\n lessons {\n id\n index\n titleKey\n lessonNumber\n paths {\n unitIndex\n lessonIndex\n curriculumLessonIndex\n sectionIndex\n index\n type\n id\n course\n resource\n scoreThreshold\n timeEstimate\n numChallenges\n numberOfChallengesSeen\n complete\n scoreCorrect\n scoreIncorrect\n scoreSkipped\n percentCorrectForDisplay\n percentIncorrect\n percentSkipped\n percentComplete\n pathCourseMenuDisplayState\n __typename\n }\n __typename\n }\n __typename\n }\n __typename\n }\n tutoringSummary {\n status\n canSchedule\n userTimezone\n nextSession {\n startTimeStamp\n lessonNumber\n unitNumber\n coachName\n __typename\n }\n __typename\n }\n}\n"}',
method: "POST",
mode: "cors",
});
const data = await res.json();
return data;
}
module.exports = getData;
- index.js
const getData = require("./getData.js");
const constants = require("./constants.json");
const makeRequest = require("./makeRequest.js");
async function main() {
const originalData = await getData();
const data = JSON.parse(JSON.stringify(originalData)).data;
console.log("Data received");
console.log(originalData);
const units = data.courseMenu.lessons((unit) =>
constants["unitsToComplete"].includes(unit.unitNumber)
);
units.forEach((unit) => {
// Start Time should reset for each unit
const startTime = Date.now() - getRndInteger(0, 86400000);
let timeSoFar = 0;
// Loop through each lesson
unit.lessons.forEach((category) => {
// Loop through each category
category.paths.forEach(
({
unitIndex,
curriculumLessonIndex,
type,
course,
numChallenges,
timeEstimate,
}) => {
// This is the lesson portion
// Randomize the time it took to complete lesson based off given estimate
const timeInMinutes =
timeEstimate +
getRndInteger(
-1 * Math.floor(timeEstimate / 3),
Math.floor(timeEstimate / 3)
);
// Convert that time to milliseconds
const timeInMilliseconds =
timeInMinutes * 60000 + getRndInteger(0, 6000);
// For randomizing how much is correct
// const percentCorrect = getRndInteger(87, 100);
// Keep track of what time it was submitted
timeSoFar += timeInMilliseconds;
// Randomize a little bit
timeSoFar += getRndInteger(0, 60000);
// Choose what percent correct is done
// Use the randomize function for a range (e.g. getRndInteger(87, 100))
const percentCorrect = getRndInteger(89, 100);
// const percentCorrect = 100;
const questionsCorrect = Math.ceil(
numChallenges * (percentCorrect / 100)
);
// Check if lesson has been completed
// Can't do if (percentCorrect == 100) because of rounding
const completed = !!(questionsCorrect == numChallenges) + "";
// The time the lesson will be marked as completed
// Will reset for each unit
let timeCompleted = startTime + timeSoFar;
makeRequest({
course,
lessonIndex: curriculumLessonIndex,
questionAmount: numChallenges,
questionsCorrect,
unitIndex: unitIndex % 4,
time: timeInMilliseconds,
type,
completed,
timeCompleted,
});
}
);
});
});
console.log("Finished (wait for requests)!!");
}
function getRndInteger(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
main();
- **makeRequest.js:
**
const data = require("./constants.json");
async function makeRequest({
course,
unitIndex,
lessonIndex,
type,
questionAmount,
time,
questionsCorrect,
completed,
timeCompleted,
}) {
console.log(
course,
unitIndex,
lessonIndex,
type,
questionAmount,
time,
questionsCorrect,
completed
);
const body =
"<path_score>n <course>" +
course +
"</course>n <unit_index>" +
unitIndex +
"</unit_index>n <lesson_index>" +
lessonIndex +
"</lesson_index>n <path_type>" +
type +
"</path_type>n <occurrence>1</occurrence>n <complete>" +
completed +
"</complete>n <score_correct>" +
questionsCorrect +
"</score_correct>n <score_incorrect>" +
(questionAmount - questionsCorrect) +
'</score_incorrect>n <score_skipped type="fmcp">0</score_skipped>n <number_of_challenges>' +
questionAmount +
"</number_of_challenges>n <delta_time>" +
time +
"</delta_time>n <version>185054</version>n <updated_at>" +
timeCompleted +
"</updated_at>n <is_lagged_review_path>false</is_lagged_review_path>n</path_score>";
const res = await fetch(
"https://tracking.rosettastone.com/ee/ce/" +
data["schoolName"] +
"/users/" +
data["userId"] +
"/path_scores?course=" +
course +
"&unit_index=" +
unitIndex +
"&lesson_index=" +
lessonIndex +
"&path_type=" +
type +
"&occurrence=1&_method=put",
{
credentials: "omit",
headers: {
"User-Agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/115.0",
Accept: "*/*",
"Accept-Language": "en-US,en;q=0.5",
"content-type": "text/xml",
"x-rosettastone-app-version": "ZoomCourse/11.11.2",
"x-rosettastone-protocol-version": "8",
"x-rosettastone-session-token": data["sessionToken"],
"Sec-Fetch-Dest": "empty",
"Sec-Fetch-Mode": "cors",
"Sec-Fetch-Site": "same-site",
},
referrer: "https://totale.rosettastone.com/",
body: body,
method: "POST",
mode: "cors",
}
);
console.log(`Status ${res.status} (200 means success)`);
console.log(`Time: ${Date().toLocaleString()}`);
}
module.exports = makeRequest;
- constants.json
{
"person": "YOUR_NAME (Not Required)",
"authorization": "YOUR_AUTHORIZATION_TOKEN",
"sessionToken": "YOUR_SESSION_TOKEN",
"schoolName": "YOUR_SCHOOL_NAME",
"unitsToComplete": [1, 2, 3],
"userId": "YOUR_USER_ID",
"languageCode": "YOUR_LANGUAGE_CODE"
}
I’m getting this error:
Data received
{
errors: [
{
error: true,
message: "Client info is not defined, and is needed in order to call Sqrl/LCP. If you're not expecting to call Sqrl/LCP via the graph server, you may need to include more necessary welcome_packet values.",
code: 'GRAPHQL_VALIDATION_FAILED',
path: [Array]
},
{
error: true,
message: "Client info is not defined, and is needed in order to call Sqrl/LCP. If you're not expecting to call Sqrl/LCP via the graph server, you may need to include more necessary welcome_packet values.",
code: 'GRAPHQL_VALIDATION_FAILED',
path: [Array]
}
],
data: { courseMenu: null, tutoringSummary: null }
}
C:UsersAdrianzDownloadsRosetta-Stone-Script-mainindex.js:10
const units = data.courseMenu.units.filter((unit) =>
^
TypeError: Cannot read properties of null (reading 'units')
at main (C:UsersAdrianzDownloadsRosetta-Stone-Script-mainindex.js:10:33)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
I tried several things:
- I tried using chatgpt to help me solve the problems but without success.
- Then I was looking at the APIs but there was no video that I could clearly understand
- I was uploading my problem to Reddit and a person told me to look for the .env files but I don’t know where they are located
What I hoped to achieve with this is that I could solve the course activities in a quick way as I did previously in the lower course.
So I leveled up in the course the whole interface changed so I don’t know how to do it