Skip to content

Instantly share code, notes, and snippets.

@mhawksey
Last active March 31, 2020 15:48
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mhawksey/5048249 to your computer and use it in GitHub Desktop.
Save mhawksey/5048249 to your computer and use it in GitHub Desktop.
Extracting an edge list from Canvas Discussion Topics API using Google Apps Script
function getCanvasDiscussionEdges() {
var canvas = "learn.canvas.net";
var type = "courses";
var id = "33";
var output = [["vert1_name","vert2_name","vert1_id","vert2_id","vert1_image_url","vert2_image_url","topic_id","topic_title","topic_url","created_at", "message_id", "message_text"]];
var doc = SpreadsheetApp.getActiveSpreadsheet();
var sheet = doc.getSheetByName("Sheet1");
var db = ScriptDb.getMyDb();
var topicList = callCanvasAPI(canvas, type, id, "discussion_topics", 50);
var participants = {}
for (i in topicList.result){
var topic = topicList.result[i];
var data = callCanvasAPI(canvas, type, id, "discussion_topics/"+topicList.result[i].id+"/view");
var participant_data = data.result.participants;
for (p in participant_data){
participants[participant_data[p].id] = participant_data[p];
}
for (j in data.result.view){
var view = data.result.view[j];
if (!view.deleted){
var vert1_name = participants[view.user_id].display_name;
var vert2_name = topic.author.display_name;
var vert1_id = view.user_id;
var vert2_id = topic.author.id;
var vert1_image_url = participants[view.user_id].avatar_image_url;
var vert2_image_url = topic.author.avatar_image_url;
var topic_id = topic.id;
var topic_title = topic.title;
var topic_url = topic.url;
var topic_url = topic.url;
var created_at = getDateFromIso(view.created_at);
var message_id = view.id;
output.push([vert1_name, vert2_name, vert1_id, vert2_id, vert1_image_url, vert2_image_url, topic_id, topic_title, topic_url, created_at, message_id, stripHTML(view.message)]);
output = output.concat(getReplies(view, participants, topic));
}
}
}
sheet.getRange(1, 1, output.length, output[0].length).setValues(output);
}
function getReplies(view, participants, topic){
var rows = [];
if (!view.deleted){
if (view.replies != undefined){
for (r in view.replies){
var reply = view.replies[r];
if (!reply.deleted){
var vert1_name = participants[reply.user_id].display_name;
var vert2_name = participants[view.user_id].display_name;
var vert1_id = reply.user_id;
var vert2_id = view.user_id;
var vert1_image_url = participants[reply.user_id].avatar_image_url;
var vert2_image_url = participants[view.user_id].avatar_image_url;
var topic_id = topic.id;
var topic_title = topic.title;
var topic_url = topic.url;
var created_at = getDateFromIso(reply.created_at);
var message_id = view.id;
rows.push([vert1_name, vert2_name, vert1_id, vert2_id, vert1_image_url, vert2_image_url, topic_id, topic_title, topic_url, created_at, message_id, stripHTML(reply.message)]);
rows = rows.concat(getReplies(reply, participants, topic));
}
}
}
}
return rows;
}
function callCanvasAPI(canvas, type, id, call, optPerPage){
var perpage = (optPerPage != undefined) ? "?per_page="+optPerPage : "";
var resp = {};
var requestData = { method: "get",
headers: { "Authorization": "Bearer " + PropertiesService.getScriptProperties().getProperty("access_token")}};
var result = UrlFetchApp.fetch("https://"+canvas+"/api/v1/"+type+"/"+id+"/"+call+perpage, requestData);
if (result.getResponseCode() == 200){
var header = result.getHeaders();
if (header.Link) {
resp.linkHeader = parseLinkHeader(header.Link).rels;
}
resp.result = JSON.parse(result.getContentText());
resp.responseCode = 200;
} else {
resp.responseCode = result.getResponseCode();
}
return resp;
}
function stripHTML(string){
var regex = /(<([^>]+)>)/ig;
return string.replace(regex, "");
}
// http://delete.me.uk/2005/03/iso8601.html
function getDateFromIso(string) {
try{
var aDate = new Date();
var regexp = "([0-9]{4})(-([0-9]{2})(-([0-9]{2})" +
"(T([0-9]{2}):([0-9]{2})(:([0-9]{2})(\.([0-9]+))?)?" +
"(Z|(([-+])([0-9]{2}):([0-9]{2})))?)?)?)?";
var d = string.match(new RegExp(regexp));
var offset = 0;
var date = new Date(d[1], 0, 1);
if (d[3]) { date.setMonth(d[3] - 1); }
if (d[5]) { date.setDate(d[5]); }
if (d[7]) { date.setHours(d[7]); }
if (d[8]) { date.setMinutes(d[8]); }
if (d[10]) { date.setSeconds(d[10]); }
if (d[12]) { date.setMilliseconds(Number("0." + d[12]) * 1000); }
if (d[14]) {
offset = (Number(d[16]) * 60) + Number(d[17]);
offset *= ((d[15] == '-') ? 1 : -1);
}
offset -= date.getTimezoneOffset();
time = (Number(date) + (offset * 60 * 1000));
return new Date(aDate.setTime(Number(time)));
} catch(e){
return;
}
}
// http://bill.burkecentral.com/2009/10/15/parsing-link-headers-with-javascript-and-java/
function parseLinkHeader(value) {
var linkexp=/<[^>]*>\s*(\s*;\s*[^\(\)<>@,;:"\/\[\]\?={} \t]+=(([^\(\)<>@,;:"\/\[\]\?={} \t]+)|("[^"]*")))*(,|$)/g;
var paramexp=/[^\(\)<>@,;:"\/\[\]\?={} \t]+=(([^\(\)<>@,;:"\/\[\]\?={} \t]+)|("[^"]*"))/g;
var matches = value.match(linkexp);
var rels = new Object();
var titles = new Object();
for (i = 0; i < matches.length; i++)
{
var split = matches[i].split('>');
var href = split[0].substring(1);
var ps = split[1];
var link = new Object();
link.href = href;
var s = ps.match(paramexp);
for (j = 0; j < s.length; j++) {
var p = s[j];
var paramsplit = p.split('=');
var name = paramsplit[0];
link[name] = unquote(paramsplit[1]);
}
if (link.rel != undefined) {
rels[link.rel] = link;
}
if (link.title != undefined) {
titles[link.title] = link;
}
}
var linkheader = new Object();
linkheader.rels = rels;
linkheader.titles = titles;
return linkheader;
}
function unquote(value) {
if (value.charAt(0) == '"' && value.charAt(value.length - 1) == '"') return value.substring(1, value.length - 1);
return value;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment