Sending messages to students in a course using the API

806 views
Skip to first unread message

Kenneth Mayer

unread,
Apr 9, 2015, 12:56:26 PM4/9/15
to canvas-l...@googlegroups.com
Does anyone have any experience with the "create conversations" API call?

/api/v1/conversations

I got this to work in a testing situation, but it's not working in my production script, and I need to send out notices tomorrow!

Here are the parameters I am posting:
 array(5) {
 ["recipients[]"]=> string(10) "course_529" 
["subject"]=> string(57) "Please fill out a Course Evaluation for TST-100_NOTE_TEST"
 ["body"]=> string(388) "Course evaluations for TST-100_NOTE_TEST are available here: https://capitol.instructure.com/courses/529/external_tools/37 Your feedback is helpful to the university and to your fellow students and will not be shared with faculty members except in statistical form and anonymously. Typically evaluations are open for submission around the last week of classes. Thank you for your help."
 ["context_code"]=> string(10) "course_529"
 ["as_user_id"]=> string(20) "sis_user_id:d1stl3rn" }

Here is the error I am getting back from Canvas: (note that the recipients[] in my post and in the Canvas API instructions is now recipients (no braces) in the response.  I tried deleting the braces, but got the same error.
array(1) { [0]=> array(2) { ["attribute"]=> string(10) "recipients" ["message"]=> string(7) "invalid" } 

By the way, I am also getting no luck with the search recipients API call in the console: $.getJSON("/api/v1/search/recipients?type=context", function(data) { console.log(data); });

Here is the PHP code for sending the message:
function postNote($id, $name, $type='notification')
{
if (true) print '<p>function postNote() '.$name.' -> '.$type.'</p>';

$rem='';
$body = 'Course evaluations for '.$name.' are available here:
Your feedback is helpful to the university and to your fellow students and will not be shared with faculty members except in statistical form and anonymously. Typically evaluations are open for submission around the last week of classes.
Thank you for your help.';
if ($type=='reminder') 
{$rem='REMINDER: ';
$body = '--->  THIS IS A REMINDER E-MAIL  <---
'.$body;
}
$info = array('recipients[]'=>'course_'.$id.'_students',
'subject'=>$rem .'Please fill out a Course Evaluation for '.$name,
'body'=> $body,
'context_code'=>'course_'.$id, 'as_user_id'=>'sis_user_id:d1stl3rn');
$test=canvasCall('conversations','POST',$info);
if (true) print var_dump($info);
if (true) print var_dump($test);
}

Thank you in advance for any help or words of wisdom.

Jared Stein

unread,
Apr 9, 2015, 11:28:06 PM4/9/15
to canvas-l...@googlegroups.com
Hey, the first thing my mind goes to without testing is the permissions of the user creating the conversation. Looks like you're masquerading, so I presume that user is enrolled in the target course with appropriate role permissions on this account?

Jared Stein

unread,
Apr 9, 2015, 11:42:22 PM4/9/15
to canvas-l...@googlegroups.com
Also (sorry, this is just occurring to me as I'm out and about) you use 'course_'.$id.'_students', -- that's not an option that I'm familiar with for recipients[]. I thought you could only specify a course, group, or individual, but tacking on "_students" suggests you can specify a role, too. Are you certain this works? I.e have you tested sending to a single user or the entire course?

Kenneth Mayer

unread,
Apr 10, 2015, 8:23:30 AM4/10/15
to canvas-l...@googlegroups.com
I thought it was a permissions issue too, but I got it to work masquerading when the user was *not* enrolled in the class and it worked that one time. I have since enrolled the user in the class as a teacher, so the user has the permissions. I have tried both with and without the _students suffix. I used _students because I viewed the API call made by Canvas when I sent a message to all the students in a course. That suffix hasn't worked for me yet.

On Thu, Apr 9, 2015 at 11:42 PM, Jared Stein <ja...@instructure.com> wrote:
Also (sorry, this is just occurring to me as I'm out and about) you use 'course_'.$id.'_students', -- that's not an option that I'm familiar with for recipients[]. I thought you could only specify a course, group, or individual, but tacking on "_students" suggests you can specify a role, too. Are you certain this works? I.e have you tested sending to a single user or the entire course?

--

---
You received this message because you are subscribed to a topic in the Google Groups "Canvas LMS Users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/canvas-lms-users/dodkzo0QAgc/unsubscribe.
To unsubscribe from this group and all its topics, send an email to canvas-lms-use...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
----------------------
Ken Mayer
ken.i...@gmail.com

Save our in-boxes! http://emailcharter.org

bki...@udel.edu

unread,
Apr 10, 2015, 8:55:48 AM4/10/15
to canvas-l...@googlegroups.com
While we are on the subject of communications, is there ever going to be an API endpoint for announcements? Not all students have notifications turned on for Conversations, but most of the faculty on our campus require that students tune into Announcements. For that matter, I wonder if there could be an endpoint for generalized communication that bypasses the Notification settings altogether. I have an LTI app that sends email directly to students using my SMTP server, and one of the things that prevents me from making that app available to the public is that there is no reliable way to push those messages out via Canvas. The other is that I'm hitting our LDAP server to get email addresses for students in a student group, rather than looping through the user endpoint to get them. If the group members endpoint would include email addresses, AND if I could just push out an email to those addresses without hitting my own server, it would pave the way for Anonymous Peer Evaluation, which is currently only available on to faculty at the University of Delaware.

Kenneth Mayer

unread,
Apr 10, 2015, 9:13:59 AM4/10/15
to canvas-l...@googlegroups.com
Jared, you are right that it does seem to be the masquerading that is causing the problem. I must not have done that on the test instance that worked. I must investigate more. Perhaps I will need to create an access token for the user I want to send the messages from.


--

---
You received this message because you are subscribed to a topic in the Google Groups "Canvas LMS Users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/canvas-lms-users/dodkzo0QAgc/unsubscribe.
To unsubscribe from this group and all its topics, send an email to canvas-lms-use...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Jared Stein

unread,
Apr 10, 2015, 12:19:12 PM4/10/15
to canvas-l...@googlegroups.com
A few things I noticed when testing this late last night:

1. course_<courseid>_students does not work. Only course_<courseid> works.

2. Even though Canvas account permissions suggest that an admin can send messages to the entire class, the API doesn't seem to let that happen. If you're an admin but not enrolled in the course with an appropriate role, the API returns that the recipients are invalid.

3. A weird quirk: If you don't specify that the message is a group_conversation, any new messages you create will automatically be filed under any existing subject line that you may already have going with participants, even if you specify a new subject. This was confusing for me in troubleshooting.

PS If you're an admin and going to masquerade as a user with an appropriate role within the course, you don't need to generate an access token for that user. I would advise against masquerading as the actual teacher unless all teachers are aware that you will be doing this on their behalf. Also, see weird quirk #3 above.

Jared Stein

unread,
Apr 10, 2015, 12:21:34 PM4/10/15
to canvas-l...@googlegroups.com
In Canvas, Announcements are just a special form of Discussions. If you check out the Discussions API documentation I think you'll see ways to specify announcements-type discussions to meet your needs.

Kenneth Mayer

unread,
Apr 10, 2015, 12:42:20 PM4/10/15
to canvas-l...@googlegroups.com
Thank you, very helpful!
I guess I need to enroll a user/admin in every class that I send a message to!
Since this account will mainly be used only to send these reminders, hopefully quirk #3 will not be a problem. But it will be a pain if a student gets all reminders to all courses in the same thread. I'll see if the context: course_51 will be in the same thread as context:course_359

BTW, If you open a FireBug/Chrome console and monitor networks and see the AJAX transmissions while you send a note to all students in the class, it uses course_<courseid>_students  but it might have a special permission that isn't available to mortals using the API.

Thanks again!

--

---
You received this message because you are subscribed to a topic in the Google Groups "Canvas LMS Users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/canvas-lms-users/dodkzo0QAgc/unsubscribe.
To unsubscribe from this group and all its topics, send an email to canvas-lms-use...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Jared Stein

unread,
Apr 10, 2015, 12:48:11 PM4/10/15
to canvas-l...@googlegroups.com
Another quick thought: Rather than enrolling a single user with a course-level role in every course (though we used to do that at UVU), you could also enroll all the students in a single Account-level Group and just message that Group. Might be easier to manage, unless you need specific messages per course.

Honestly I don't really understand how the context_codes work, at least in combination with batch conversation messages.

Kenneth Mayer

unread,
Apr 10, 2015, 1:16:48 PM4/10/15
to canvas-l...@googlegroups.com
I guess I have to send it as a group_conversation. 
Otherwise all of the notices go to the same thread.

Becky Kinney

unread,
Apr 10, 2015, 3:02:19 PM4/10/15
to canvas-l...@googlegroups.com
Aha! That's a great tip about Discussion/Announcements. Thank you, Jared!

Becky Kinney
Academic Technology Services

--

---
You received this message because you are subscribed to the Google Groups "Canvas LMS Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to canvas-lms-use...@googlegroups.com.

Kenneth Mayer

unread,
Apr 14, 2015, 2:12:47 PM4/14/15
to canvas-l...@googlegroups.com
OK, I have it working now, mainly by first enrolling the admin in each class, then finding the section in that class, and then posting the message (creating the convo).
Interestingly, none of the convos show up in the admin's sent box, so to confirm/check that all is well for all the classes, I have to do it manually.

Here is the code that worked:

function postNote($canvas_course_id, $canvas_course_name, $code, $type='notification')
{
$sect = sectionFind($canvas_course_id,$canvas_course_name);

$rem='';
$body = 'Course evaluations for '.$code.' are available here:

Your feedback is helpful to the university and to your fellow students and will not be shared with faculty members except in statistical form and anonymously. 
Typically evaluations are open for submission around the last week of classes.

Thank you for your help.';
if ($type=='reminder') 
{$rem='REMINDER: ';
$body = '--->  THIS IS A REMINDER E-MAIL  <---
'.$body;
}
$info = array(
'subject'=>$rem .'Please fill out a Course Evaluation for '.$code,
'recipients[]'=>$sect,
'body'=> $body,
'group_conversation'=> true,
'course'=>'course_'.$canvas_course_id,
'access_token'=>access_token,
'context_code'=>'course_'.$canvas_course_id);
$test=canvasCall('conversations','POST',$info);
}

function enrollUser($user,$cid)
{
$info = array('enrollment[user_id]'=>$user,
'enrollment[type]'=>'TaEnrollment',
'enrollment[enrollment_state]'=>'active');
$ret = canvasCall('courses/'.$cid.'/enrollments','POST',$info);
return $ret;
}

function sectionFind($id, $name)
{
$info = array('type'=>'context',
'search'=>$name,
'per_page'=>60,
'synthetic_contexts'=>'true',
'permissions[]'=>'send_messages_all',
'context'=>'course_'.$id
);
$sections=canvasCall('search/recipients','GET',$info);
$ret='';
foreach($sections as $sect)
{
if (isset($sect['id']))
{
$ret = $sect['id'];
}
}
return $ret;
}

I'm not sure *WHAT* will happen if there are more than one section in the course. So far that hasn't happened yet. I need to write a filter to make sure that the section found is the correct one.

Thoughts?

Ken


Kenneth Mayer

unread,
Apr 24, 2015, 3:23:21 PM4/24/15
to canvas-l...@googlegroups.com
Another dumb question about conversations. If I want to message several users, I have to add each user id as 'recipients[]'. For example, I tested sending a message to three users in Canvas and here are the post variables as viewed in Chrome's Developer Tools:
  1. group_conversation:
    true
  2. course:
    course_205
  3. context_code:
    course_205
  4. recipients[]:
    35
  5. recipients[]:
    36
  6. recipients[]:
    37
  7. subject:
    Testing messager--please ignore

How should I post three (or more) variables with duplicate names using PHP? I'm using http_build_query($info) in my main Canvas call subroutine, but I guess I have to unpack it somehow because the array $info can't have multiple variables with the same key, right?

Thank you for pointing me to the right (and probably obvious) way.

Ken

On Thursday, April 9, 2015 at 12:56:26 PM UTC-4, Kenneth Mayer wrote:

Kenneth Mayer

unread,
Apr 24, 2015, 3:53:15 PM4/24/15
to canvas-l...@googlegroups.com
OK--I think I have the answer from here:
in the section Example #3 http_build_query() with complex arrays

--

---
You received this message because you are subscribed to a topic in the Google Groups "Canvas LMS Users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/canvas-lms-users/dodkzo0QAgc/unsubscribe.
To unsubscribe from this group and all its topics, send an email to canvas-lms-use...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages