Greasy Fork is available in English.

QRespostas++

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

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