How to Submit to an External Tool Type Assignment?

Jump to solution
d_tan
Community Participant

First follow the steps here to create an Assignment of submission type External tool.

How do I add an external app as an assignment submission type? 

My question is how do a student submit anything to this assignment? Is it through the external tool by calling the Canvas API? If so then what API method and how to set the input parameters?

I tried to use the following API method

POST /v1/courses/{course_id}/assignments/{assignment_id}/submissions

submission[submission_type] = basic_lti_launch

submission[url] = some url

The result is

{ "status": "unauthorised", "errors": [ { "message": "user not authorised to perform that action" } ] }

For comparison, I did the same test against a "submission type = online_url" assignment, same user, same API token, same course. same input parameters except the submission[submission_type]. Both assignments do not have due date set. And that one works fine.

Thanks 

Labels (2)
1 Solution
michael_vasily-
Community Novice

I had the exact issue but I finally figured out that external tools can't use the canvas REST api to submit grades.   You have to follow the LTI protocol.   The canvas docs have the details explained here: Grade Passback Tools - Canvas LMS REST API Documentation 

If you are using java to implement your provider, you can use this library that makes posting grades easy:

Maven Repository: org.imsglobal » basiclti-util 

You use IMSPOXRequest.buildReplaceResult(...);

Here is an example:

  

  DefaultHttpClient httpClient = new DefaultHttpClient();

        HttpParams httpParams = httpClient.getParams();

        HttpConnectionParams.setConnectionTimeout(httpParams, TIMEOUT_SECONDS*1000);

        HttpConnectionParams.setSoTimeout(httpParams, TIMEOUT_SECONDS*1000);

        

        HttpPost httpPost = IMSPOXRequest.buildReplaceResult(canvasUrl, key, secret, sourceId, score, null, true);

        

        HttpResponse httpResponse = httpClient.execute(httpPost);

        int statusCode = httpResponse.getStatusLine().getStatusCode();

        if(statusCode == 401) {

            LOG.error("Unauthorized refresh token request. Wrong client_id or secret?");

            HttpEntity errorEntity = httpResponse.getEntity();

            if(errorEntity != null) {

                String errorBody = EntityUtils.toString(errorEntity);

                LOG.error("Response from Canvas: " + errorBody);

            }

            return ;

        }

        if(statusCode != 200) {

            LOG.error("Non-200 status code ( " + statusCode + " )returned while requesting an access token at URL "canvasUrl);

            HttpEntity errorEntity = httpResponse.getEntity();

            if(errorEntity != null) {

                String errorBody = EntityUtils.toString(errorEntity);

                LOG.error("Response from Canvas: " + errorBody);

            }

            return ;

        }

update: I had a small bug in the code.  The above code is now correct with the latest version of basiclti-util .

View solution in original post