QRespostas++

This script add the functionality to Qmágico(formally Eduqo) to view answers and to watch vídeo automatitlly.

Tendrás que instalar una extensión para tu navegador como Tampermonkey, Greasemonkey o Violentmonkey si quieres utilizar este script.

You will need to install an extension such as Tampermonkey to install this script.

Tendrás que instalar una extensión como Tampermonkey o Violentmonkey para instalar este script.

Necesitarás instalar una extensión como Tampermonkey o Userscripts para instalar este script.

Tendrás que instalar una extensión como Tampermonkey antes de poder instalar este script.

Necesitarás instalar una extensión para administrar scripts de usuario si quieres instalar este script.

(Ya tengo un administrador de scripts de usuario, déjame instalarlo)

Tendrás que instalar una extensión como Stylus antes de poder instalar este script.

Tendrás que instalar una extensión como Stylus antes de poder instalar este script.

Tendrás que instalar una extensión como Stylus antes de poder instalar este script.

Para poder instalar esto tendrás que instalar primero una extensión de estilos de usuario.

Para poder instalar esto tendrás que instalar primero una extensión de estilos de usuario.

Para poder instalar esto tendrás que instalar primero una extensión de estilos de usuario.

(Ya tengo un administrador de estilos de usuario, déjame instalarlo)

// ==UserScript==
// @name QRespostas++
// @namespace https://github.com/sirmonteiro
// @license MIT
// @description This script add the functionality to Qmágico(formally Eduqo) to view answers and to watch vídeo automatitlly.
// @description:pt-BR Esse script adiciona a funcionalidade para o Qmágico(formalmente Eduqo) de ver respostas e assistir vídeos automaticamente.
// @version 0.1.3
// @icon https://i.imgur.com/9IV3lZq.png
// @match https://*.qmagico.com.br/cadernos/caderno/*
// @match https://*.qmagico.com.br/atividades/resolver/*
// @grant unsafeWindow
// @grant GM.getValue
// @grant GM.setValue
// @grant GM.deleteValue
// ==/UserScript==

(function (open) {
  let answerLetters = ["A", "B", "C", "D", "E"];
  unsafeWindow.XMLHttpRequest.prototype.open = function () {
    this.addEventListener(
      "readystatechange",
      async function () {
        if (this.readyState == "4" && this.status == 200) {
          let response = JSON.parse(this.response);

          if (this.responseURL.includes("api/get_token_data")) {
            let userID = response.user_id;
            GM.setValue("userID", userID);
          }

          if (
            this.responseURL.includes(
              "rest_api/qplano_rest_api/api/load_caderno"
            )
          ) {
            let cadernoID = response.caderno.id.toString();
            GM.setValue("cadernoID", cadernoID);
          }

          if (this.responseURL.includes("api/get_content")) {
            let exerciselistID = response.id.toString();
            let exerciseKind = response.kind;
            if (exerciseKind == "EXERCISELIST") {
              let exercicesIDs = [];
              response.data.contents.forEach((exercise) => {
                exercicesIDs.push(exercise.id);
              });

              GM.setValue("exercicesIDs", exercicesIDs);
            }
            GM.setValue("exerciselistID", exerciselistID);
            GM.setValue("exerciseKind", exerciseKind);
          }

          if (
            this.responseURL.includes(
              "rest_api/resolver_atividades_rest_api/api/save_state"
            )
          ) {
            if (
              !document.getElementById("scriptbtndiv") &&
              document.getElementsByClassName("exam-card-body")[0]
            ) {
              let exerciseBoxDiv = document.createElement("div");
              exerciseBoxDiv.id = "scriptbtndiv";
              exerciseBoxDiv.style.display = "flex";
              exerciseBoxDiv.style.justifyContent = "center";
              exerciseBoxDiv.style.marginBottom = "16px";
              exerciseBoxDiv.innerHTML = `
                <button class='btn btn-large' id='pausebtn'>Pausar atividade</button>        
              `;
              document
                .getElementsByClassName("exam-card-body")[0]
                .appendChild(exerciseBoxDiv);
              let pausebtn = document.getElementById("pausebtn");
              pausebtn.addEventListener("click", async () => {
                alert(
                  "Atividade pausada, o tempo que você ficou fora da aba não será contado!"
                );
              });
            }
          }

          if (this.responseURL.includes("rest_api/metrics_rest_api/api/save")) {
            if (
              !document.getElementById("scriptbtndiv") &&
              document.getElementsByClassName("emg-exercise-box-padding")[0]
            ) {
              let exerciseBoxDiv = document.createElement("div");
              exerciseBoxDiv.style.display = "inline";
              exerciseBoxDiv.id = "scriptbtndiv";
              exerciseBoxDiv.innerHTML = `
              <button class='btn btn-large' id='answerbtn'>Ver resposta</button>
              `;

              document
                .getElementsByClassName("emg-exercise-box-padding")[0]
                .appendChild(exerciseBoxDiv);
              let answerbtn = document.getElementById("answerbtn");
              answerbtn.addEventListener("click", async () => {
                answerbtn.classList.add("btn-progress");
                answerbtn.classList.add("btn-progress-diagonal");

                let actualExercise = Number(
                  document
                    .getElementsByClassName("box-title")[0]
                    .innerText.split(" ")[1]
                );

                let userID = await GM.getValue("userID");
                let cadernoID = await GM.getValue("cadernoID");
                let exerciselistID = await GM.getValue("exerciselistID");
                let exercicesIDs = await GM.getValue("exercicesIDs");

                let bodyManipulado = `metrics=[{"action":"ContentAccessLog","content_id":"","creation":1000000000000.0,"time_spent_milis":13304,"context":{"page":"VISUALIZAR_CURSO+-+MAIN","course_id":""},"last_update":1000000000000.0,"closed":true},{"action":"ContentAccessLog","user_id":"${userID}","content_id":"${
                  exercicesIDs[actualExercise - 1]
                }","creation":1000000000000,"time_spent_milis":0,"exerciselist":{"id":${exerciselistID},"kind":"EXERCISELIST","metadata":{},"data":{"content_ids":[]}},"context":{"page":"VISUALIZAR_CURSO+-+MAIN","course_id":"${cadernoID}"}}]`;

                await fetch(
                  "https://integradaeducativa.qmagico.com.br/rest_api/metrics_rest_api/api/save",
                  {
                    credentials: "include",
                    headers: {
                      "User-Agent":
                        "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0) Gecko/20100101 Firefox/86.0",
                      Accept: "application/json, text/plain, */*",
                      "Accept-Language": "pt-BR,en-US;q=0.7,en;q=0.3",
                      "Content-Type":
                        "application/x-www-form-urlencoded;charset=utf-8",
                      "X-Requested-With": "XMLHttpRequest",
                    },
                    body: bodyManipulado,
                    method: "POST",
                    mode: "cors",
                  }
                )
                  .then(async (res) => {
                    let data = await res.json();
                    if (res.ok) {
                      // let exercise = (data[0].log.question_index) + 1
                      // let alternative = answerLetters[data[0].content.data.answers.correct_answer]
                      let correctAnswerIndex =
                        data[0].content.data.answers.correct_answer;
                      let answerdiv = document.createElement("div");
                      if (
                        !data[0].content.data.answers.correct_answer.toString()
                      ) {
                        let answerComment =
                          data[0].content.data.answers.comment;
                        if (!answerComment) {
                          answerComment =
                            "<h3>Infelizmente o professor não colocou comentário da resposta :(</h3>";
                        }
                        answerdiv.innerHTML = `
                  <div class="divisor-line divisor-line-darker" />
                  <div class='emg-exercise-gabarito'>
                    <div class='emg-exercise-gabarito-comentario p-margin-2'>
                      <strong class='emg-exercise-gabarito-comentario-title'>Comentário da resposta</strong>
                      <span style='font-size: 12pt'>
                      ${answerComment}
                      </span>
                    </div>
                  </div>
                  `;
                      } else {
                        answerdiv.innerHTML = `
                  <div class="divisor-line divisor-line-emboss" />
                  <div class='emg-exercise-gabarito'>
                    <p class='emg-exercise-gabarito-label'>
                      <strong>
                        Resposta correta:
                        <span class="badge badge-circle badge-small badge-success">
                        ${answerLetters[correctAnswerIndex]}
                        </span>
                      </strong>
                    </p>
                  </div>
                  `;
                        document
                          .getElementsByClassName(
                            "emg-exercise-multiple-choice-answer-item"
                          )
                          [correctAnswerIndex].click();
                      }
                      document
                        .getElementsByClassName("emg-exercise-footer")[0]
                        .appendChild(answerdiv);
                      answerbtn.classList.remove("btn-progress");
                      answerbtn.classList.remove("btn-progress-diagonal");
                      answerbtn.disabled = "disabled";
                      GM.deleteValue(exerciselistID);
                      GM.deleteValue(exercicesIDs);
                      // alert(exercise + ':' + alternative)
                    } else {
                      console.log("erro", res.status);
                    }
                  })
                  .catch((err) => {
                    throw err;
                  });
              });
            }
          }

          if (
            this.responseURL.includes(
              "rest_api/listing_rest_api/home/list_my_interactions"
            )
          ) {
            if (
              (await GM.getValue("exerciseKind", false)) == "VIDEO" &&
              !document.getElementById("scriptbtndiv")
            ) {
              let scriptbtndiv = document.createElement("div");
              scriptbtndiv.id = "scriptbtndiv";
              scriptbtndiv.innerHTML = `
              <button class='btn btn-large' id='videobtn'>Assistir Vídeo</button>
              `;
              document
                .getElementsByClassName("qm-content-toolbar-actions-wrapper")[0]
                .insertAdjacentElement("afterbegin", scriptbtndiv);

              let videobtn = document.getElementById("videobtn");
              videobtn.addEventListener("click", async () => {
                videobtn.classList.add("btn-progress");
                videobtn.classList.add("btn-progress-diagonal");

                let userID = await GM.getValue("userID");
                let cadernoID = await GM.getValue("cadernoID");
                let videoID = await GM.getValue("exerciselistID");

                let videoBody = `metrics=[{"action":"ContentInteraction","kind":"VIDEO","user_id":"${userID}","content_id":"${videoID}","creation":1000000000000,"last_update":1000000000000,"accesses":0,"context":{"page":"VISUALIZAR_CURSO+-+MAIN","course_id":"${cadernoID}"},"key":"","stop":20000}]`;

                await fetch(
                  "https://integradaeducativa.qmagico.com.br/rest_api/metrics_rest_api/api/save",
                  {
                    credentials: "include",
                    headers: {
                      "User-Agent":
                        "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0) Gecko/20100101 Firefox/86.0",
                      Accept: "application/json, text/plain, */*",
                      "Accept-Language": "pt-BR,en-US;q=0.7,en;q=0.3",
                      "Content-Type":
                        "application/x-www-form-urlencoded;charset=utf-8",
                      "X-Requested-With": "XMLHttpRequest",
                    },
                    body: videoBody,
                    method: "POST",
                    mode: "cors",
                  }
                )
                  .then((res) => {
                    if (res.ok && res.status == 200) {
                      videobtn.classList.remove("btn-progress");
                      videobtn.classList.remove("btn-progress-diagonal");
                      videobtn.disabled = "disabled";
                      GM.deleteValue(videoID);
                      location.reload();
                    } else {
                      console.log("erro", res.status);
                    }
                  })
                  .catch((err) => {
                    throw err;
                  });
              });
            }
          }
        }
      },
      false
    );
    open.apply(this, arguments);
  };
})(unsafeWindow.XMLHttpRequest.prototype.open);