I confirmed with Clerk that there is no webhook for the active org switching, and no way to get that information upon change.
Here's where I ended up: I have the code below as a customFunction that pulls the user and active organization from the session details into the context. The trick, as I mentioned in my first post, is that I updated Clerk's JWT token to send the active organization ID through the "language" parameter.
mutation,
customCtx(async (ctx) => {
const { clerkUserId, clerkOrganizationId } = await getUserInfo(ctx);
if (clerkUserId === undefined) {
throw new ConvexError("Not authenticated");
}
if (clerkOrganizationId === undefined) {
throw new ConvexError("No active organization");
}
const user = await getOneFromOrThrow(
ctx.db,
"users",
"by_clerkId",
clerkUserId
);
const organization = await getOneFromOrThrow(
ctx.db,
"organizations",
"by_clerkId",
clerkOrganizationId,
"clerkId"
);
const userId = user._id;
const orgId = organization._id;
return { orgId, userId };
})
);
async function getUserInfo(ctx: { auth: Auth }) {
const authInfo = await ctx.auth.getUserIdentity();
return {
clerkUserId: authInfo?.subject,
clerkOrganizationId: authInfo?.language,
};
}```
So replacing all of my mutations with mutationWithOrganizationUser (and likewise with a separate custom query) I'm able to get the org ID and user ID through context.
The only caveat I've run into is that it is not reactive to a change in the active organization. So if you're feeding the org ID directly as a argument (which is not secure) changing the active org would trigger a re-render from convex. The session data does not do that. So my solution was just to force a redirect to my homepage on changing your org, which works just fine so far in testing.