Originally posted on 9/9/2013 on the Valence Developer Blog by Sarah-Beth Bianchi.
This week's API Cookbook recipe covers using submissions and folders in dropbox. We will look at managing folders, retrieving and passing in submissions, and fetching a submission's categories.
Problem
You want to retrieve the list of folders available in your dropbox.
Solution
To retrieve the list of folders in dropbox, you should query for the folders directory within your org unit. An example query might fetch the essay submission folders for a class.
GET /d2l/api/le/1.0/6606/dropbox/folders/
Response: 200 OK
[
{
"Id": 1,
"CategoryId": 1000,
"Name": "Midterm essays",
"CustomInstructions": {
"Text": "Please ensure that your document is formatted properly",
"Html": "<p>Please ensure that your document is formatted properly</p>"
},
"Attachments": [],
"TotalFiles": 0,
"UnreadFiles": 0,
"FlaggedFiles": 0,
"TotalUsers": 10038,
"TotalUsersWithSubmissions": 0,
"TotalUsersWithFeedback": 0,
"Availability": null,
"Assessment": {
"ScoreDenominator": null,
"Rubrics": []
}
},
{
"Id": 2,
"CategoryId": 1000,
"Name": "Final essays",
"CustomInstructions": {
"Text": "Please ensure that your submission is formatted properly",
"Html": "<p>Please ensure that your submission is formatted properly</p>"
},
"Attachments": [],
"TotalFiles": 5,
"UnreadFiles": 2,
"FlaggedFiles": 0,
"TotalUsers": 10038,
"TotalUsersWithSubmissions": 0,
"TotalUsersWithFeedback": 0,
"Availability": null,
"Assessment": {
"ScoreDenominator": null,
"Rubrics": []
}
}
]
Note: If this query returns an empty block, you do not have any folders in your dropbox. You can add a folder by logging onto your LMS, selecting Dropbox and adding a new folder from there.
If you are looking for a particular folder, you can specify the folder id in your request. From our previous example, our midterm essays folder has folder id 1, so the call to retrieve it would look like the following:
GET /d2l/api/le/1.0/6606/dropbox/folders/1
Response: 200 OK
{
"Id": 1,
"CategoryId": 1000,
"Name": "Midterm essays on French Revolution",
"CustomInstructions": {
"Text": "Please ensure that your submission is formatted properly",
"Html": "<p>Please ensure that your submission is formatted properly</p>"
},
"Attachments": [],
"TotalFiles": 0,
"UnreadFiles": 0,
"FlaggedFiles": 0,
"TotalUsers": 10038,
"TotalUsersWithSubmissions": 0,
"TotalUsersWithFeedback": 0,
"Availability": null,
"Assessment": {
"ScoreDenominator": null,
"Rubrics": []
}
}
Problem
You want a list of submissions within a folder.
Solution
If you want a list of all submissions, you can specify the query to include the folders directory followed by the folder id, and then request the submissions directory.
GET /d2l/api/le/1.0/6606/dropbox/folders/1/submissions/
Response: 200 OK
[
{
"Entity": {
"DisplayName": "Gatno Hart",
"EntityId": 169,
"EntityType": "User"
},
"Feedback": null,
"Submissions": [ {
"Id": 1,
"SubmittedBy": {
"Identifier": "169",
"DisplayName": "Gatno Hart"
},
"SubmissionDate": "2013-06-21T17:32:19.783Z",
"Comment": {
"Text": "Final submission",
"Html": "<p>Final submission</p>"
},
"Files": [ {
"IsRead": true,
"IsFlagged": false,
"FileId": 1,
"FileName": "file1.txt",
"Size": 16
} ]
},
{
"Id": 2,
"SubmittedBy": {
"Identifier": "170",
"DisplayName": "Major Backic"
},
"SubmissionDate": "2013-06-21T18:16:58.747Z",
"Comment": {
"Text": "My first submission",
"Html": "<p>My first submission</p>"
},
"Files": [ {
"IsRead": true,
"IsFlagged": false,
"FileId": 2,
"FileName": "file2.txt",
"Size": 16
} ]
},
{
"Id": 3,
"SubmittedBy": {
"Identifier": "170",
"DisplayName": "Major Backic"
},
"SubmissionDate": "2013-06-21T18:16:58.747Z",
"Comment": {
"Text": "My revised submission",
"Html": "<p>My revised submission</p>"
},
"Files": [ {
"IsRead": true,
"IsFlagged": false,
"FileId": 3,
"FileName": "file3.txt",
"Size": 16
} ]
} ]
}
]
The response gives you the information on all submissions which includes past submissions from the user. If the file in a submission is deleted, the submission will still pop up in the response, however the 'Files' array would be empty as the file no longer exists.
If you need to retrieve a particular submission, you can filter the results by specifying the files directory followed by the file id in the request.
GET /d2l/api/le/1.0/6606/dropbox/folders/1/submissions/1/files/2
Response: 200 OK
This sentence is part of the content in the submission.
Problem
You want to submit a file to your dropbox.
Solution
In order to submit a file to your dropbox through the API, you need to write a script that passes in the content headers described below into the appropriate dropbox route.
The request should be a multipart submission where the first part is a JSON array passing in a description of the submission. The second part of the submission is an octet-stream which reads in the binary data of the file and is decoded by the LMS. This allows for the submission of content rich files such as pictures, word documents or simply plain text.
A sample request to upload an image which follows these content headers may look like the following:
POST /d2l/api/le/1.0/6606/dropbox/folders/1/submissions/mysubmissions/
Content-Type: application/json
{
"Text": "This is my revised submission.",
"HTML": "<p>This is my revised submission.</p>"
}
Content-Disposition: form-data; name="Diagram of Battlefield"; filename="mydiagram.png"
Content-Type: application/octet-stream
Problem
You want to retrieve the categories defined in your dropbox.
Solution
To retrieve all categories defined in your dropbox, include the categories directory in your API request.
GET /d2l/api/le/1.0/6606/dropbox/categories/
Response: 200 OK
[{
"Id": 1000,
"Name": "Section 1 Submissions"
},
{
"Id": 2000,
"Name": "Section 2 Submissions"
},
{
"Id": 3000,
"Name": "Section 3 submissions"
}]
If this request returns an empty array, then there are no categories listed in your dropbox. To add a new category, visit your LMS's dropbox feature, edit the desired dropbox folder and create a new category.
To retrieve a specific category, fetch the categories directory followed by the category id. In this case, to retrieve the Section 1 Submission from our previous example, use the following API calls:
GET /d2l/api/le/1.0/6606/dropbox/categories/1000
Response: 200 OK
{
"Folders": [{
"Id": 1,
"CategoryId": 1000,
"Name": "Section 1 Submission",
"CustomInstructions": {
"Text": "",
"Html": ""
},
"Attachments": [{
"FileId": 15,
"FileName": "category_criterion.txt",
"Size": 16314
}],
"TotalFiles": 1102,
"UnreadFiles": 1101,
"FlaggedFiles": 0,
"TotalUsers": 10038,
"TotalUsersWithSubmissions": 1,
"TotalUsersWithFeedback": 0,
"Availability": null,
"Assessment": {
"ScoreDenominator": null,
"Rubrics": []
},
"GroupTypeId": null,
"DueDate": null
}],
"Id": 1000,
"Name": "Test"
}
Problem
You want to set the feedback for a user including changing the overall score or the criteria outcome in the rubric.
Solution
To fetch the feedback for the dropbox folder for a particular user/entity, you can specify the feedback request using the entity id. An example request for user 169 may look like the following:
GET /d2l/api/le/1.0/6606/dropbox/folders/1/feedback/User/169
Response: 200 OK
{
"Files": [{
"FileId": 1106,
"FileName": "myfile.txt",
"Size": 74
}],
"Score": 80.360000000,
"Feedback": {
"Text": "This is the overall feedback along with criterion feedback.",
"Html": "<p>This is the overall feedback along with criterion feedback.</p>"
},
"RubricAssessments": [{
"RubricId": 5,
"OverallScore": 10.000000000,
"OverallFeedback": {
"Text": "This is the overall feedback.",
"Html": "<p>This is the overall feedback.</p>"
},
"OverallLevel": {
"LevelId": 20,
"Feedback": {
"Text": "",
"Html": ""
}
},
"OverallScoreOverridden": true,
"OverallFeedbackOverridden": true,
"CriteriaOutcome": [{
"CriterionId": 4,
"LevelId": 15,
"Score": 3.000000000,
"ScoreIsOverridden": true,
"Feedback": {
"Text": "Criterion 1 Feedback",
"Html": "<p>Criterion 1 Feedback</p>"
},
"FeedbackIsOverridden": true
},
{
"CriterionId": 5,
"LevelId": 15,
"Score": 3.000000000,
"ScoreIsOverridden": true,
"Feedback": {
"Text": "Criterion 2 Feedback",
"Html": "<p>Criterion 2 Feedback</p>"
},
"FeedbackIsOverridden": true
},
{
"CriterionId": 6,
"LevelId": 15,
"Score": 3.000000000,
"ScoreIsOverridden": true,
"Feedback": {
"Text": "Criterion 3 Feedback",
"Html": "<p>Criterion 3 Feedback</p>"
},
"FeedbackIsOverridden": true
}]
}]
}
Note: At this time, the feedback array in the OverallLevel cannot be set through an API call.
Problem
You want to add or modify feedback for an entity or user.
Solution
To add or modify feedback for the user, you can specify the DropboxFeedback JSON block in your input with the appropriate score, overall score (sum of the criterion points) or other components of the rubric, including CriteriaOutcome. If you want the service to re-calculate the overall level associated with the feedback for the submission, you should provide null for the OverallLevel property in the data block you provide.
POST /d2l/api/le/1.0/6606/dropbox/folders/1/feedback/User/169
{
"Score": 90.50,
"Feedback": {
"Text": "This is the overall feedback along with criterion feedback.",
"Html": "<p>This is the overall feedback along with criterion feedback.</p>"
},
"RubricAssessments": [ {
"RubricId": 5,
"OverallScore": 10.00,
"OverallFeedback":{
"Text": "This is simply the overall feedback.",
"Html": "<p>This is simply the overall feedback.</p>"
},
"OverallLevel": {
"LevelId": 20,
"Feedback":{
"Text": "",
"Html": ""
}
},
"OverallScoreOverridden": true,
"OverallFeedbackOverridden": true,
"CriteriaOutcome": []
} ],
"IsGraded": false
}
Response: 200 OK
{
"Files": [],
"Score": 90.50000000,
"Feedback": {
"Text": "This is the overall feedback along with criterion feedback.",
"Html": "<p>This is the overall feedback along with criterion feedback.</p>"
},
"RubricAssessments": [{
"RubricId": 5,
"OverallScore": 10.000000000,
"OverallFeedback": {
"Text": "This is simply the overall feedback.",
"Html": "<p>This is simply the overall feedback.</p>"
},
"OverallLevel": {
"LevelId": 20,
"Feedback": {
"Text": "",
"Html": ""
}
},
"OverallScoreOverridden": true,
"OverallFeedbackOverridden": true,
"CriteriaOutcome": [{
"CriterionId": 4,
"LevelId": 15,
"Score": 3.000000000,
"ScoreIsOverridden": false,
"Feedback": {
"Text": "Criterion 1 Feedback",
"Html": "<p>Criterion 1 Feedback</p>"
},
"FeedbackIsOverridden": true
},
{
"CriterionId": 5,
"LevelId": 14,
"Score": 4.000000000,
"ScoreIsOverridden": false,
"Feedback": {
"Text": "Criterion 2 Feedback",
"Html": "<p>Criterion 2 Feedback</p>"
},
"FeedbackIsOverridden": true
},
{
"CriterionId": 6,
"LevelId": 14,
"Score": 4.000000000,
"ScoreIsOverridden": false,
"Feedback": {
"Text": "Criterion 3 Feedback",
"Html": "<p>Criterion 3 Feedback</p>"
},
"FeedbackIsOverridden": true
}]
}]
}
This concludes our examination of the dropbox APIs.