AnsweredAssumed Answered

GET Request working on browser, but failing in Postman

Question asked by Allan Yanik on Mar 1, 2019
Latest reply on Mar 7, 2019 by Allan Yanik

Hello, everyone!

 

Recently I've been tasked to build an LTI that tells us if the user has seen a determined page inside a course. I know it's really simple and they could just do it by checking the usage page:

/courses/:courseId/users/:userId/usage

 

However this would be too much work to check each and every student, so around december I've written a script in JavaScript that works well in the developer console and it works fine, but there is a small problem with it: it requires me to run it on every course page manually, and the functions couldn't be called as soon as the page loaded, they needed to be run one at a time. So naturally, the solution would be an LTI since the results from this is meant for the teachers to access. 

 

If anyone is interested in testing, here it is: 

// Must be run on People's page inside a course

const canvas = `https://${instituion}.instructure.com/`
const usersPage = `${canvas}users/`
const coursesPage = `${canvas}courses/`
const courseUsers = window.location.href.split('/courses/')[1]
let pageViewed = pagename

function getUserIds() {
  $('tr').each(function () {

    const id = this.id.split('user_')[1]
    id === undefined ?
      null : userIds = [...userIds, id]
  })
}

function getUserData() {
  userIds.forEach(id => {

    /* institution.instructure.com/users/userId.json */
    $.get(`${usersPage}${id}.json`).done(function (resp) {
      userData = [...userData, {

        id: resp.id,
        login: resp.login_id,
        name: resp.name
      }]
    })
  })
}

function getUserActivity() {
  userIds.forEach(id => {

    /* This is the page we are looking for, every user's access to the page */
    $.get(`${coursesPage}${courseUsers}/${id}/usage.json`).done(function (resp) {
      userActivity = [...userActivity, resp]
    })
  })
}

function filterActivity() {
  userActivity.forEach(data => {
    data.forEach(activity => {

      /* This is the data we're looking for */
      const shortcut = activity.asset_user_access

      activityData = [...activityData, {

        id: shortcut.user_id,
        /* ISO Format. Take out the T sou you get YYYY-MM-DD */
        lastSeen: shortcut.last_access.split('T')[0],
        page: shortcut.display_name
      }]
    })
  })
}

function fuseData() {
  for (let i in userData) {
    /* finally getting there */
    userActions[userData[i]['id']] = {

      'login': userData[i]['login'],
      'nome': userData[i]['name'],
      'acessos': []
    }
  }

  for (let i in activityData) {
   
    pageViewed.includes(activityData[i]['page']) ?
      userActions[activityData[i]['id']]['acessos'].push({

        page: activityData[i]['page'],
        visited: activityData[i]['lastSeen']
      }) : false
  }
}

// Last step. Run one function at a time
JSON.stringify(userActions)

 

Then I noticed that if I convert that to an LTI that's run inside a course, I won't be able to use these since the LTI would be a standalone page running inside Canvas and global variables such as ENV won't be avaliable to me to make my life easier. 

 

So I started converting it to PHP and it everything was working just fine, until I got an Error 402 (Unauthorized) while trying to make a request. 

 

I was using Postman to make the cURL request for me, and it works fine on any page other than the usage.json page. I am an Admin btw, so the problem isn't on my permissions or my token. 

 

So the basic problem is: I can't access the page

/courses/:courseId/users/:userId/usage.json

via LTI or via Postman it says I'm Unauthorized. However if I just go to the URL on my browser it works fine (as long as I'm logged in our Canvas instance)

Anyone has been there before or have any ideas on how to tackle this problem? 

I'm new around here, so I'm sorry if the post was longer than it should be. I just wanted to give out as many details as I could. 
I'm also unable to share directly with the Canvas Devs group.

Outcomes