Analytics: Identify users to Rudderstack by externalUserId where available (#47325)

* wip

* tests

* move util, fix test

* fixes

* Update public/app/core/services/echo/utils.ts

Co-authored-by: kay delaney <45561153+kaydelaney@users.noreply.github.com>

Co-authored-by: kay delaney <45561153+kaydelaney@users.noreply.github.com>
This commit is contained in:
Josh Hunt 2022-04-05 16:41:22 +01:00 committed by GitHub
parent 3fff301367
commit 1b27e55e5a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 62 additions and 3 deletions

View File

@ -93,6 +93,7 @@ export type OAuthSettings = Partial<Record<OAuth, { name: string; icon?: string
export interface CurrentUserDTO {
isSignedIn: boolean;
id: number;
externalUserId: string;
login: string;
email: string;
name: string;

View File

@ -11,6 +11,7 @@ export class User implements CurrentUserInternal {
login: string;
email: string;
name: string;
externalUserId: string;
lightTheme: boolean;
orgCount: number;
orgId: number;
@ -34,6 +35,7 @@ export class User implements CurrentUserInternal {
this.orgId = 0;
this.orgName = '';
this.login = '';
this.externalUserId = '';
this.orgCount = 0;
this.timezone = '';
this.fiscalYearStartMonth = 0;

View File

@ -7,12 +7,13 @@ import {
isPageviewEvent,
PageviewEchoEvent,
} from '@grafana/runtime';
import { User } from '../sentry/types';
import { CurrentUserDTO } from '@grafana/data';
import { getUserIdentifier } from '../../utils';
export interface RudderstackBackendOptions {
writeKey: string;
dataPlaneUrl: string;
user?: User;
user?: CurrentUserDTO;
sdkUrl?: string;
configUrl?: string;
}
@ -57,7 +58,9 @@ export class RudderstackBackend implements EchoBackend<PageviewEchoEvent, Rudder
(rds as any).load(options.writeKey, options.dataPlaneUrl, { configUrl: options.configUrl });
if (options.user) {
(rds as any).identify(options.user.email, {
const identifier = getUserIdentifier(options.user);
(rds as any).identify(identifier, {
email: options.user.email,
orgId: options.user.orgId,
});

View File

@ -0,0 +1,38 @@
import { CurrentUserDTO, OrgRole } from '@grafana/data';
import { getUserIdentifier } from './utils';
const baseUser: CurrentUserDTO = {
isSignedIn: true,
id: 3,
login: 'myUsername',
email: 'email@example.com',
name: 'My Name',
lightTheme: false,
orgCount: 1,
orgId: 1,
orgName: 'Main Org.',
orgRole: OrgRole.Admin,
isGrafanaAdmin: false,
gravatarUrl: '/avatar/abc-123',
timezone: 'browser',
weekStart: 'browser',
locale: 'en-AU',
externalUserId: '',
};
const gcomUser: CurrentUserDTO = {
...baseUser,
externalUserId: 'abc-123',
};
describe('echo getUserIdentifier', () => {
it('should return the external user ID (gcom ID) if available', () => {
const id = getUserIdentifier(gcomUser);
expect(id).toBe('abc-123');
});
it('should fall back to the email address', () => {
const id = getUserIdentifier(baseUser);
expect(id).toBe('email@example.com');
});
});

View File

@ -1,5 +1,20 @@
import { attachDebugger, createLogger } from '@grafana/ui';
import { CurrentUserDTO } from '@grafana/data';
/**
* Returns an opaque identifier for a user, for reporting purposes.
* Because this is for use when reporting across multiple Grafana installations
* It cannot simply be user.id because that's not unique across two installations.
*/
export function getUserIdentifier(user: CurrentUserDTO) {
if (user.externalUserId.length) {
return user.externalUserId;
}
return user.email;
}
/** @internal */
export const echoLogger = createLogger('EchoSrv');
export const echoLog = echoLogger.logger;