QRespostas++

Esse script adiciona a funcionalidade para o Qmágico(formalmente Eduqo) de ver respostas e assistir vídeos automaticamente.

Você precisará instalar uma extensão como Tampermonkey, Greasemonkey ou Violentmonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey ou Violentmonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey ou Userscripts para instalar este script.

Você precisará instalar uma extensão como o Tampermonkey para instalar este script.

Você precisará instalar um gerenciador de scripts de usuário para instalar este script.

(Eu já tenho um gerenciador de scripts de usuário, me deixe instalá-lo!)

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

(Eu já possuo um gerenciador de estilos de usuário, me deixar fazer a instalação!)

// ==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);