Best endpoint for when a user was "last active"

Jump to solution
paul14
Partner
Partner

Hi all,

I'm prototyping an integration which messages students who haven't logged into Canvas for over a month.

I was planning on using the "?include=last_login" parameter on the /api/v1/users/ endpoint and using that as the basis of the reminder.

Just curious if anybody knows what generates this value? Is it only updated for a full authentication event (i.e. filling in the login screen)?

Would there be a better way to obtain the last time a person was active in Canvas?

Kind regards,
Paul

0 Likes
1 Solution

Good catch, @matthew_buckett . This is why I shouldn't try to throw something together in a hurry when I need to be somewhere else before I even start.

Canvas is pushing us towards GraphQL, but their current implementation of it is not as powerful or useful as the REST API in many cases (for me at least). I also find it harder to work with, I have to know the actual structure of the data instead of just having an array of objects to iterate through. I actually use the REST API to get the last activity and total time from the enrollments API. The REST API gives the total time spent in the course as well (graphql does not). I was trying to make it happen with GraphQL based on statements about where things are headed.

There is not a usersConnection under the account, you have to go through the coursesConnection to get to it. It's reasons like this that I don't like the push to GraphQL. With the REST API, the way to get the full list of users is through the Accounts API, but with GraphQL, you cannot get a user unless they're enrolled in a course.

In my rush to get the message finished, I missed that there was an enrollmentsConnection under the coursesConnection and introduced an extra layer of complexity into the query by involving the usersConnection.

Because of the lack of filtering involved, I would actually start with a list of all of the courses in the account, do some filtering on my own, and then fetch the enrollments for each of those courses. At least that's how I do it currently and it would avoid having to download the 12,679 enrollments for the student resources course we put all students into.

One problem of using the enrollments to get the lastActivityAt field is that if a student is enrolled in multiple sections within a course, then you will get a separate entry, with the same lastActivityAt value, for each.

Here is a better GraphQL query than what I had the first time. It only gives one entry for each user (subject to the multiple enrollments) rather than duplicating them. I've also added a filter to restrict it to just the student enrollments (this excludes the test student).

query MyQuery {
  account(id: "12345") {
    coursesConnection(first: 2) {
      nodes {
        _id
        enrollmentsConnection(filter: {types: StudentEnrollment}) {
          nodes {
            lastActivityAt
            user {
              _id
            }
          }
        }
      }
    }
  }
}

 

There is another approach. If you had a specific user in mind and wanted to know their last substantial activity in any course, you could request the last activity for all courses for that one user and then take the most recent value. 

query MyQuery {
  legacyNode(_id: "123", type: User) {
    ... on User {
      enrollments {
        lastActivityAt
      }
      _id
    }
  }
}

 

Technically, you don't need to return the _id for the user since you know who the user is. I often write scripts that gather the information in an asynchronous call and save it as part of a bigger report and it is easier if that information is completely contained within the response rather than having to track it from the request.

View solution in original post