Thinkific webhoook quirks: tracking a user's sign-in activity
We really like Thinkific, but its webhooks are a little peculiar. Here’s one example.
There’s a user.signup webhook which fires when a new user account is created.
This fires when an end user creates an account directly.
It also fires when an administrator creates an account for an end user.
The payload doesn’t provide any way to differentiate these, which is a shame.
There’s also a user.signin webhook which fires when an end user logs in.
This does not fire when a user goes through a “email me a password reset link” flow, even though that flow ends with the user logged in without having to go through the login form.
It also does not fire when a user creates an account, even though that flow ends with the user logged in without having to go through the login form.
Unfortunately, this combination of choices means that there's both false positives and false negatives when we're trying to monitor a user's login activity:
We can listen only for the "user signin" events, but then we won't mark the user as having logged in when they first creates an account for themselves.
Or we can listen also for the "user signup" events, but then we will wrongly mark the user as having logged in when an admin creates an account for them.
Either way, we have no clear way to notice when a user forgets their password, gets logged in from that password reset flow, and then takes some actions.
The upshot is that it’s surprisingly difficult to extract answers to “when did Jane Smith last visit our Thinkific site” and “how many times has Jane Smith logged in overall” programmatically.
The Thinkific admin does does display answers to these questions which seem accurate, and they appear to do it with GraphQL:
query CurrentUserListForLayout($first: Int, $filter: UserFilter, $orderBy: OrderBy, $after: String) {
site {
id
users(first: $first, filter: $filter, orderBy: $orderBy, after: $after) {
totalCount
pageInfo {
[...]
}
edges {
node {
[...]
signInCount
lastSignIn
}
}
}
}
}
But those signInCount
and lastSignIn
fields aren’t listed in their public GraphQL docs so I suspect they aren’t available. (I haven’t tried yet, but I’ve encountered other cases where they give themselves more GraphQL access than they give us.)
Anyway, if anyone has a workaround here I’d love to hear it!