Celebrate Excellence in Education: Nominate Outstanding Educators by April 15!
Found this content helpful? Log in or sign up to leave a like!
Currently, we are trying to use the live event webhooks to send notifications to users of our app. When an event occurs Canvas hits our API, the API parses out the needed info (like user_id) and makes a request to an internal API that sends a push notification to our app users.
We are testing this out first with the Grades events since the user_id is included in the body, making it easier to send to the user it pertains to.
While testing I noticed that a course_grade_change event will have the user_id set as expected like so:
{
user_id: '90',
course_id: '70',
workflow_state: 'active',
created_at: '2020-09-22T20:12:57Z',
updated_at: '2021-04-14T15:39:44Z',
current_score: 96.67,
old_current_score: 93.33,
final_score: 31.52,
old_final_score: 30.43,
unposted_current_score: 96.67,
old_unposted_current_score: 93.33,
unposted_final_score: 31.52,
old_unposted_final_score: 30.43
}
but the grade_change event seems to prefix all ids, including the user_id, with a random number like so:
{
submission_id: '111910000000000846',
assignment_id: '111910000000000083',
assignment_name: '.NET',
grade: '143',
old_grade: '145',
score: { numberStr: '143.0' },
old_score: { numberStr: '145.0' },
points_possible: { numberStr: '150.0' },
old_points_possible: { numberStr: '150.0' },
grader_id: '111910000000000066',
student_id: '111910000000000090',
user_id: '111910000000000090',
grading_complete: true,
muted: false
}
So I guess this brings about two questions. Is this expected? If so how should I go about determining what the prefix is in order to get all the correct ids? I could assume that I just need to parse out the numbers in the end after all the zeros but that seems fragile.
Solved! Go to Solution.
Hi Jacob,
I can't speak to whether or not this is expected in these particular live events, but the long numbers are Canvas' globally-unique IDs. Many objects in Canvas have a local (to a particular Canvas instance) ID and a globally-unique ID. The Canvas IDs are relatively short, like your user_id of 90 below. The globally-unique IDs are long (like 111910000000000090), and incorporate the unique "shard ID" of the specific Canvas instance that they belong to.
From your example events, I can tell that the shard ID for your Canvas instance is 11191. This value is available as a custom LTI launch parameter that Canvas can send to your tool -- search for "Canvas.shard.id" on this page: https://canvas.instructure.com/doc/api/file.tools_variable_substitutions.html for more info.
The formula for converting between local Canvas IDs and globally-unique IDs is:
(shard_id * 10000000000000) + local_id = global_id
or
global_id - (shard_id * 10000000000000) = local_id
Hope this is helpful!
--Colin
Hi Jacob,
I can't speak to whether or not this is expected in these particular live events, but the long numbers are Canvas' globally-unique IDs. Many objects in Canvas have a local (to a particular Canvas instance) ID and a globally-unique ID. The Canvas IDs are relatively short, like your user_id of 90 below. The globally-unique IDs are long (like 111910000000000090), and incorporate the unique "shard ID" of the specific Canvas instance that they belong to.
From your example events, I can tell that the shard ID for your Canvas instance is 11191. This value is available as a custom LTI launch parameter that Canvas can send to your tool -- search for "Canvas.shard.id" on this page: https://canvas.instructure.com/doc/api/file.tools_variable_substitutions.html for more info.
The formula for converting between local Canvas IDs and globally-unique IDs is:
(shard_id * 10000000000000) + local_id = global_id
or
global_id - (shard_id * 10000000000000) = local_id
Hope this is helpful!
--Colin
Hey Colin,
That's very helpful. I completely skipped over the Live Events Metadata section where that info is explained. I was able to parse out the local_id based on that.
Thank you!
Jacob
Hey Colin,
Since there's always going to be the same amount of zeros I could regex replace /\d+00000000000(\d+)/ with $1. Do you think I need to get the shardid in order to get the localid or is it fine to use a regex to determine the localid? Mostly asking because we aren't using an LTI and not sure if there's some way to determine the shardid through an event handler.
Best,
Jacob
That's a good question; my gut is that a regex would probably work fine, but out of curiosity I looked to see how Canvas computes these IDs itself, and I found the details in Instructure's Switchman library:
https://github.com/instructure/switchman/blob/master/app/models/switchman/shard.rb
I don't really read Ruby, but I worked out that it's essentially using this logic:
To get the local ID from a global ID:
local_id = global_id % 10000000000000
To get the shard ID from a global ID:
shard_id = int( global_id / 10000000000000 )
That's pretty straightforward, and should be safe since that's how Canvas does it! 🙂
--Colin
To participate in the Instructure Community, you need to sign up or log in:
Sign In