Assigning Intra-Group Peer Reviews

Community Champion
25 50 23.6K

Quick Install

For those power users who are impatient, here are the quick install steps.

  1. Install the Tampermonkey browser extension for Chrome, Firefox, or Safari
  2. Install the Intra-Group Peer Reviews user script.
  3. Navigate to a Peer Review page for an assignment and notice the Intra-Group Reviews section
  4. Set the Group Set to use. This may not be necessary as it attempts to detect which one to use for you.
  5. Click the Assign IntraGroup Reviews button.

If you run into problems, be sure to come back and read the instructions. In particular, if you're using a custom URL for your Canvas instance and not *, see the section on customization.


It is sometimes useful to assign peer reviews to the other people in the group, rather than to people in different groups. I use them for students to provide appreciative and constructive feedback to their team members about their work in a team that week. Others may have other uses.

Basically, it's a pain to do this and since Canvas already has a list of who is in what group, it should be something that can be automated. That's what this script does.

Canvas Implementation

The current implementation within Canvas makes this very difficult. The peer reviews are assigned by name, not by group.

Common but Inefficient Workflow

The typical workflow would be to start at the top of the peer review page because that's where most of the work needs done.

Peer Reviews

I want to start with Bizarre Ability, but I don't know who is in her group. To find that out, I need to go to the People page and pull up the Accountability group set. I don't see Bizarre's name, what I see is this:

Student Groups

Except that I have 32 of those groups and have no idea which one Bizarre is in. I start expanding them ... one by one ... because there is no button to expand them all.

I finally find her -- she was in group 30 out of 32.

Group Members

Now I switch back to the Peer Review page. I click on the button to Give Bizarre Ability another submission to assess and am presented with a dropdown list of all of the students in the class.

Assign Peer Review to Student

I scroll all the way down to S, looking for Selfish Hog, before I realize that the list of names on the People page is their first name followed by the their last name while on the drop down list, it's last name followed by first name and I should really be going to the H for Hog.

All right, I finally get Hog, Selfish and Sentence, Clicking added to Ability, Bizarre.

Now it's time to move on to Ruby Accolade, I mean Accolade, Ruby. Except I'm going to be smarter about it. Before moving on to Ruby, I'm going to go take care of Selfish Hog and Clicking Sentence while I know who is in their group.

Slightly Better Workflow

What I just described wasn't the most efficient way. What would be better would be to start on the People page with the first group.

Group Member Details

Then I go to the Peer Review page and take of Radical, Stellar, Spiritual, and Unspoken. Then I repeat that process with the second group. Then the third, and so on, until all 32 groups have been assigned.

End Result

No matter which method I use, I still end up with assigning 355 peer reviews by hand. That takes way too long and makes me reconsider how important it is that I do intra-group peer reviews.

Before you argue that you would never have 32 groups, I had another groupset with only 12 groups of about 10 students each. That turned into 1141 peer reviews that needed assigned.

Of course, this wasn't my real class. My real class only has 30 students in it and had 103 peer reviews, but some people have larger classes and the problem of assigning intra-group peer reviews is even worse than I've described.

If there are n students and the average group size is k, then there will be about n*(k-1) assignments that need made.

Automatic Assignment

Now that we've seen how Canvas does things, let's look at what this user script does.

It adds a new block below Canvas' Automatically Assign Peer Reviews

Intra-Group Reivews

You may need to pick the group set.

Choose Group Set

You click the button and you wait. There is a progress bar that shows while it's working so you have a sense of how much more there is to go. Each advance represents one student being assigned their peer reviews. There's a slight pause at the end while it catches up (probably inefficient programming on my part) and then the page reloads.

When the page reloads, you now have this.

Peer Reviews

Those 355 peer review assignments took my script about 30 seconds to complete. The 1141 peer reviews for the other group set took about 58 seconds. That was on a the test instance of Canvas over a DSL connection, your results may vary.


I made a video so you could see it in action.

The Little Things ...

There are some things you may have not noticed, possibly because they weren't mentioned.

Automatically Picking the Group Set

If your class only has one group set in it, then it defaults to that group set rather than making you choose it. It also defaults to a particular group set if the assignment you're attaching the peer reviews to is a group assignment.

Proper? Sorting of Group Sets

The list of group sets is sorted alphabetically. I had, in order, Accountability, Communication, Project 1, Project 2, and Project 10.

Wait a minute! You know from other frustrations with Canvas that Project 10 is between Project 1 and Project 2. Well, alphabetically it is, but I threw in a little hack that will work most of the time except when it doesn't work.

The trick was to left-pad all of the numbers with 0's and then take the right-most 5 digits. 5 was an arbitrary number, but I figured that someone wouldn't have more than 100,000 group sets in their course. However, if someone named their group sets by zip+4 codes, which are 9 digits long, then it would not look good. Those people are free to modify the code to add extra 0's and use a longer string.

Interrupting and Restarting

The code only runs while you are on the page. That means that if you leave the page while it's assigning the peer reviews that it will not finish.

Luckily, all you need to do to finish the job is to come back, reload the page, and click the button again. It scans the list to see which peer reviews still need to be assigned so it picks up where it left off.

It only reloads the page if it assigns peer reviews. If you are completely done assigning and you try it again, it will show the progress bar at 100% and leave it there.

Reviews Assigned to the Entire Group

This program does not try to assign each a fixed number of peer reviews like you can do with Canvas' automatically assign. It just assigns peer reviews to everyone who is in your group. If you're on a team with 3 people, you get 2 peer reviews to complete. If you're on a team with 10 people, then you get 9 peer reviews.


This should work out of the box for people who are hosted by Instructure and have their Canvas instance ending in If your institution uses a custom domain like, then you will need to modify the // @match statement on line 5 to match your instance.

The only other customization is a Boolean flag on line 12 called reloadPageWhenFinished. It defaults to true, meaning to reload the page when finished. If you don't want the page to reload, then change that to false. I figured most people wanted to see the changes when they were made, but I made it a configuration option just in case. 

Technical Details

Most people probably don't care, but this is the first script I've written that tries to use a more modern version of JavaScript including Promises, the Fetch API, const and let instead of var, and arrow functions. It results in cleaner looking code and those things are supported on recent versions of the major browsers, but it probably won't work on older versions of the browsers.

Anyway, as my first script, I may not have everything right, especially with the Promises. But it works and is definitely easier than manually assigning the peer reviews, so I'm making it available to people.

Submissions are Still Required

This script does not attempt to get around the Canvas requirement that a submission be made before students can complete the peer reviews.

In my class, I have students provide feedback using peer reviews on an assignment different than the one they're turning in. That way I can assign a different rubric to their peer reviews than what I'm using for the project. As a separate assignment, there is no submission. It turns out that in Canvas, the peer review links that you get by going to the assignment page are tied to the submission for that assignment. For on paper or no submission assignments this doesn't happen until the instructor puts a grade into the grade book.

Even when there is a submission allowed, Canvas doesn't show anything until there is a submission made. Here is what Bizarre Ability sees from the assignment page before she has turned in the assignment.

Assignment Details

There is no list of peer reviews.

However, if she goes to the To Do list that we tell students not to use, then she sees this:

Student To Do List

There are two peer reviews that she needs to complete, but she has no idea who they are for.

When Bizarre goes click on the first one, she sees a screen and the only place she knows who she is responding to is in the breadcrumb.

Student Peer Review


This probably helps explains why one of less-tech-savvy students put feedback for all of the peer reviews into a single submission comment.

At least the item disappeared from the To Do list once it was completed.

What I've started doing in my class is faking a submission for every student and assigning them a default grade in the grade book. Of course I use 0 because I want them to know what will happen if they don't complete the assignment, but then you have to deal with "Why did I get a 0 for this?" because they didn't read the instructions on the assignment because they clicked on the To Do list instead of the assignment.

Once the grade is entered, then they see the submission details and the list of students who they need to peer review. In this case, Bizarre had already provided feedback to Clicking Sentence from the To Do list.

Student Assignment Details

Update 2021-02-03

When I wrote the script, the browser limited the number of concurrent connections to 5 or 6 per host. That built-in limiting was enough to keep from hitting the Canvas throttling restrictions. Since then, things have gotten more efficient and the script began hitting those limits and then failing.  @mjennings has been after me for a while to fix this, but it hasn't been as a high priority as teaching my classes. I added throttling to another script a couple of days ago and decided to tackle another one while my mind was still on how to do it. The change could have taken less than 10 lines of code, but I took time to rework and update the script.

Canvas has an x-rate-limit-remaining value that starts at 700 and if it gets to 0, then it fails and basically stops responding. You can avoid reaching 0 by limiting the number of concurrent requests and staggering the requests so they don't all hit at the same time.

The script now uses the Bottleneck library to restrict the maximum number of concurrent requests to 10 and makes sure that there is at least a 20 ms delay between requests. In my beta instance, I tested a course with 369 students and 74 groups of 4-5 each. It took about 4 seconds to load all of the students and then about 45 seconds to assign 1472 peer reviews. The x-rate-limit-remaining never dropped below 569. This is actually faster than when I wrote the original script and it took 58 seconds to assign 1141 reviews (although using the test instance instead of beta).

There is the potential for speeding it up even more, but I decided to play nice with the API, siding on the error of taking more time but making sure it worked as opposed to doing it as quickly as possible. If you want to speed it up, then change the debug constant to true and it will log timings to the console in the browser's developer tools.

I also cleaned up some code through a linter and found a bug in detecting the next link for pagination.


There are a couple of threads in the Community that are related to this.