Register for InstructureCon25 • Passes include access to all sessions, the expo hall, entertainment and networking events, meals, and extraterrestrial encounters.
Found this content helpful? Log in or sign up to leave a like!
Hi,
I'm developing an integration using the Canvas API and we desperately need the essay question answer text available via the API. Getting it via file download is not acceptable.
The 'undocumented feature' mentioned in https://community.canvaslms.com/t5/Developers-Group/How-get-all-answers-from-a-quiz-using-the-API/td... does not work. There is no such 'submission_data' portion in the response.
What I have are quizzes and in each quiz there can be text answers to essay questions. Is there an API endpoint now that can give me the students' text answers to essay questions?
Hi @nm8
Did you find a way to solve it? I'm searching the Canvas API and I can't find an endpoint for that.
Regards.
The solution I gave in the other thread still works for me. I just created a new quiz and tested it to confirm it. You are using classic quizzes and not new quizzes, right?
In regards to @nm8 , the submission_data is under the submission_history array, it's not a direct child of the main array.
I'm not saying it's there for you -- just confirming that it still works for me. Are you getting the submission_history property at all and it just doesn't have submission_data or are you not getting the submission_history?
Hi @James
In the other thread you mentioned "Is your test a practice test or an ungraded survey? They may not have assignments associated with them. One thing you could do (without testing) is go to your beta instance, change it to be a graded assignment, and then get the results as I described above".
In my case, I used an "ungraded survey." I did the test (switch to "graded assignment") in the beta environment but it doesn't work, I can't get the answers from the students.
Any advice?
Regards.
I must have missed that we were talking about ungraded surveys. They don't have assignment IDs and the normal approach doesn't work. At least I mentioned that I didn't test changing the type. Thanks for looking into that.
I didn't write a massive essay, but for an ungraded survey, I was able to go into Quiz Statistics and generate the student analysis and get the essay response there. That's not full-proof, it will strip out any HTML-ish characters like < or >. You can use the Quiz Reports API to create and monitor the progress on creating the report.
Not satisfied with that answer, I then went in and changed the ungraded survey to a graded survey. I was able to get an assignment_id that way, but when I fetched the submission_history, it was there without the submission_data that you needed. It appears that submission_data is tied to a submission and there is no assignment submission for an ungraded survey. When I look at the quiz submission endpoint, it returns a quiz_submissions object that has a quiz_submission_id (called id), but the submission_id is null.
Many things dealing with classic quizzes are delivered as part of the HTML page and not loaded via JSON through the API. After searching for things, it seems this is the case for the student answers (I may have written that at some point -- I've written too much to remember it all). I use that trick with SpeedGrader and QuizWiz where I modify the content that Canvas delivers as HTML.
What that means is that you could download the student response as HTML and then parse the page to get the student responses. The request is a non-API call (needs to be made within a browser, perhaps with a headless browser).
If you are signed in as the user taking the quiz, then the request has the form
where version is the attempt number.
That includes all of the other crap that's on the page (navigation, etc). What you really want is just the quiz and you probably want it for people other than the user who is logged in. To get that information, I borrowed some stuff I learned from SpeedGrader / Moderate Quiz.
That gives you just the quiz results (the headless=1 does that) for the specified user (provided you have permissions to view it).
Take the quiz and convert it to a DOM object so you can refer to items. For Node JS, I use jsdom, but there are other ways. If you're using Chrome with Puppeteer, you can let Chrome do the DOM parsing for you.
The selector that will give you the answer to an essay question is
That means you can do something like one of these two lines. The first line keeps the HTML and the second one returns plaintext.
document.querySelectorAll('div.display_question.question.essay_question div.user_content.quiz_response_text.enhanced').forEach(e => console.log(e.innerHTML));
document.querySelectorAll('div.display_question.question.essay_question div.user_content.quiz_response_text.enhanced').forEach(e => console.log(e.textContent));
Now, what you'll probably want to do, unless there is just one essay question, is to break that up and stop with the selector for the first div. You can get the ID of that element to get the question ID. Alternatively, you could have an index that let you know which essay question they were answering. This could be good if the ungraded survey was consistent but in different classes where the IDs were different.
Here's some code that gives the text of the question and the text of the response. Again, you could use innerHTML if you want to keep the formatting (you likely do).
document.querySelectorAll('div.display_question.question.essay_question').forEach(e => {
const q = e.querySelector('div.question_text.user_content.enhanced').textContent.trim();
const r = e.querySelector('div.user_content.quiz_response_text.enhanced').textContent.trim();
console.log(`Question : ${q}`);
console.log(`Response : ${r}`);
});
Instead of console.log(), you would probably want to save the results somewhere.
Putting that all together, you can use the Get all quiz submissions endpoint of the API to get a list of all the submissions. You will need course_id and quiz_id to make that call. From the response, you'll need to grab the user_id and attempt. Then, in a headless browser, you iterate through all of the users who have submissions and get their quiz history. If I needed all attempts, then I would iterate through the versions 1..attempt, but if you just need the latest response, then use version=attempt.
You could do the whole thing in a headless browser, it's just that the call to get the quiz history is not an API call. By running a headless browser, you can have it do the parsing for you.
For my headless browser work, I don't actually use a headless browser (well, for some things I do). I use Puppeteer that connects to a real Chrome browser via the remote debugging port. That allows me to get logged in to the site and address any MFA that might be required. After I've logged in, then I run my script. Depending on your requirements for logging into Canvas, that may not be necessary and it might be that you could do it completely with a headless browser.
I'm glad you were able to get it working.
I thought there might be an opportunity for a userscript that would add a button to a survey and allow people to download the results. For large classes, that might run into script timeout issues. You would also need to figure out the best way to return the results, whether that be a JSON file or a tab-delimited. Excel can accept up to 32KB in a cell, but that might not be enough for some essays (I have some posts here in the Community I cannot edit to correct because of length limitations).
In the end, I decided I had other projects that I need to get done and a remotely-controlled browser session is probably better than a userscript. People wanting this capability are probably wanting it for large numbers of surveys across multiple courses.
There are many SMS providers in the market who can provide you with SMS services but I would suggest you be careful where you invest your money as there is a lot of Fly-By-Night Bulk SMS provider in the market. I would suggest you check out SMSala platform they have the highest delivery rates and are presently the No.1 SMS platform in worldwide.
To interact with Panda Bot in the Instructure Community, you need to sign up or log in:
Sign In