The Instructure Community will enter a read-only state on November 22, 2025 as we prepare to migrate to our new Community platform in early December. Read our blog post for more info about this change.
Hello all. I was contacted recently about the spring 2022 NSSE survey that requires unique links sent to several thousand graduating seniors. This page has some information about how this is accomplished in Canvas using an excel with formulas and a script in power shell. The description is a bit vague and to be honest I'm clueless about how this works.
This survey is sent to students emails as well so the LMS is just a reminder (the students get the link in their canvas inbox) Since they already receive an email, I don't see this as a huge priority...
Has anyone had any luck using a script like the one linked above to send unique messages to several thousand students' canvas inboxes?
Thanks!
It looks like they copied that info from a previous Canvas Community thread on NSSE + Canvas. You might have some luck posting in there?
Speaking for my institution, we're still posting the general link to the survey as an announcement in Canvas.
@james_umphres1 did you have any luck with using the script?
The same as James in his prior post, we are trying to use the API calls to load Conversations with unique URLs per student. The NSSE site provides a sample and we've modified it to get the messages created on the display, however we keep getting a 400 Bad Request error on the Invoke line. Any ideas as to what we might have incorrect?
$token = "modified for sharing"
$canvas_domain = "ourschool.test.instructure.com"
$headers = @{"Authorization"="Bearer "+$token}
Write Host $headers
Import-Csv C:\Users\myuser\Documents\NSSE\IndividualizedSurveylinks.csv | ForEach-Object {
$user_id = $_.user_id
$first_name = $_.first_name
$survey_url = $_."survey_url"
$uri = "https://"+$canvas_domain+"/api/v1/conversations/?
recipients[]=$user_id&subject=NSSE Survey&body=$first_name, `r`nPlease take the NSSE Survey. `r`nEach survey is especially designed for you. `r`n$survey_url"
Write-Host $uri
Invoke-RestMethod -Method POST -uri $uri -Headers $headers
}
I don't use PowerShell or NSSE, but let me take a stab at it anyway.
Does your CSV file have the Canvas ID or the SIS ID?
It needs to be the Canvas ID or you need to preface it with sis_user_id: to tell it that it is a SIS ID. The SIS IDs page in the API documentation explains more.
The 400 status code means it is a bad request that could not be understood. It could be due to sending a non-numeric user ID. The Canvas IDs are numeric and if your user IDs in the CSV file have are not, it could be the problem.
The post on the NSSE site mentioned that the NSSE file had to be converted to Canvas User IDs. If you miss that step, it certainly falls in line with question I asked. If the NSSE student_id is not your SIS ID, then you would have to do some further conversion to get either the Canvas ID or the SIS ID for the user.
I cannot speak to the PowerShell aspect other than the approach used of putting all the material into the query string is not typically used for a POST. The Microsoft documentation for the Invoke-RestMethod shows more structured ways. My initial guess is the user ID issue, though.
If it turns out that isn't the issue, then you might look into debugging and looking at what is actually sent to the Canvas server. The query string should be URI encoded. I don't know if PowerShell does that automatically. If it doesn't, then it might work for the person that wrote it because they have no special characters in their user names. If the survey URL contained a query string and it wasn't encoded properly, then Canvas might see that as part of the its URL and misinterpret it. My guess is that is not the issue, just trying to think of other ways that it could go wrong.
Do you recommend any other tools?
I'm using the SIS ID from Canvas, but I've also tried the Canvas ID and gotten the same results. Then I tried just sending one user with no csv file and still get the same error.
$token = "3~eGucGuUj9M40VL3K2brKIx0xO3OW6iZeTMHfQn2NgAyzsukqMsYhMPSzRgFuei9k"
$canvas_domain = "yourschool.test.instructure.com"
$headers = @{"Authorization"="Bearer "+$token}
Write Host $headers
$user_id = 1988888
$first_name = 'Jimmie'
$survey_url = 'https://nssesurvey.org/PE379ABD9D/60'
$uri = "https://"+$canvas_domain+"/api/v1/conversations/?
recipients[]=$user_id$user_id&subject=NSSE Survey&body=$first_name, `r`nPlease take the NSSE Survey. `r`nEach survey is especially designed for you.
`r`n$survey_url"
Write-Host $uri
Invoke-RestMethod -Method POST -uri $uri -Headers $headers
The correct values are being sent, including the Canvas ID.
Name Value
---- -----
Authorization Bearer 3~eGucGuUj9M40VL3K2brKIx0xO3OW6iZeTMHfQn2NgAyzsukqMsYhMPSzRgFuei9k
https://yourschool.test.instructure.com/api/v1/conversations/?
recipients[]=1988888&subject=NSSE Survey&body=Jimmie,
Please take the NSSE Survey.
Each survey is especially designed for you.
Four things jump out, but I'm not sure that any of them are the culprit. The fourth one has a higher probability of being the issue than the first three.
You are not encoding your query string -- or at least not when you're logging it. That may not be the issue, though. I just tested the API call (not using Powershell) and it worked. I did have to convert my \r\n to %0D%0A to get it to recognize it. If my URL contained a question mark, it was okay, but if there was an ampersand, then it would have to be encoded, otherwise anything after it gets stripped. Your example NSSE code looks like it should be fine.
The second thing that jumps out is to make sure that you are using your school's Canvas hostname. You put yourschool.test.instructure.com. At first, I just figured you were doing that to hide your school's domain, but then you just posted an access token in a public forum, so I'm not sure. If that is a long term token, it should be immediately deleted. I still don't think this is it, the message that I sent successfully in the first part failed with a 404 error (not found) rather than a 400 (bad request) when I tried using it.
The third thing is to make sure that person the token belongs to has a relationship with the person you're sending it to. My token is to an admin account and can see everyone. But if I was a non-admin teacher trying to send to a student, it wouldn't work. I would probably get a 401 code (unauthorized) rather than 400 if this happened. I did test sending with a bogus token and got the 401 error.
The fourth thing I would check is to make sure there is not an embedded newline in what you are sending. I don't know if it's the way you pasted into the Community or the way it is in your code, but you have a line break after the ? before the recipients parameter. I would make sure that everything within a double quotes is on a single line, using a + to concatenate multiple strings together if necessary. Of all the things I've seen and considered, this is the most likely to generate a 400 (bad request) code instead of a different message.
Here's what I would do.
Make sure there are not multiple lines within double quotes and try it again. If that doesn't work, then try this:
Send yourself (rather than someone else) a very simple message. Don't make it part of a CSV import, just a very short script to test the sending. Don't put in any newlines don't put in the link. I used something like this (but with my real Canvas ID). Not shown, but you do need the authorization header in there.
POST <instance>/api/v1/conversations?recipients[]=12345&subject=test&body=test+message
If that works, then start making it more complex. Add in the new lines and test again. If that works, then add in the link. If it breaks somewhere along the way, then we know where to look.
Community helpTo interact with Panda Bot, our automated chatbot, you need to sign up or log in:
Sign inTo interact with Panda Bot, our automated chatbot, you need to sign up or log in:
Sign in
This discussion post is outdated and has been archived. Please use the Community question forums and official documentation for the most current and accurate information.