How can I fix this problem and make it work properly?

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:

  1. I tried using chatgpt to help me solve the problems but without success.
  2. Then I was looking at the APIs but there was no video that I could clearly understand
  3. 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