diff --git a/lib/message/log_message.ts b/lib/message/log_message.ts index 2e9180535..39a5e33fd 100644 --- a/lib/message/log_message.ts +++ b/lib/message/log_message.ts @@ -69,6 +69,7 @@ export const INVALIDATE_CMAB_CACHE = 'Invalidating CMAB cache for user %s and ru export const CMAB_CACHE_HIT = 'Cache hit for user %s and rule %s.'; export const CMAB_CACHE_ATTRIBUTES_MISMATCH = 'CMAB cache attributes mismatch for user %s and rule %s, fetching new decision.'; export const CMAB_CACHE_MISS = 'Cache miss for user %s and rule %s.'; +export const ODP_IDENTIFY_NOT_DISPATCHED= 'ODP identify event is not dispatched (fewer than 2 valid identifiers).' export const messages: string[] = []; diff --git a/lib/odp/odp_manager.spec.ts b/lib/odp/odp_manager.spec.ts index 9ae0daf69..3cc8c4532 100644 --- a/lib/odp/odp_manager.spec.ts +++ b/lib/odp/odp_manager.spec.ts @@ -618,7 +618,7 @@ describe('DefaultOdpManager', () => { expect(identifiers).toEqual(new Map([['fs_user_id', 'user'], ['vuid', 'vuid_a']])); }); - it('sends identified event when called with just fs_user_id in first parameter', async () => { + it('does not send identified event when called with just fs_user_id (single identifier)', async () => { const eventManager = getMockOdpEventManager(); eventManager.onRunning.mockReturnValue(Promise.resolve()); @@ -634,12 +634,10 @@ describe('DefaultOdpManager', () => { await odpManager.onRunning(); odpManager.identifyUser('user'); - expect(mockSendEvents).toHaveBeenCalledOnce(); - const { identifiers } = mockSendEvents.mock.calls[0][0]; - expect(identifiers).toEqual(new Map([['fs_user_id', 'user']])); + expect(mockSendEvents).not.toHaveBeenCalled(); }); - it('sends identified event when called with just vuid in first parameter', async () => { + it('does not send identified event when called with just vuid (single identifier)', async () => { const eventManager = getMockOdpEventManager(); eventManager.onRunning.mockReturnValue(Promise.resolve()); @@ -655,9 +653,7 @@ describe('DefaultOdpManager', () => { await odpManager.onRunning(); odpManager.identifyUser('vuid_a'); - expect(mockSendEvents).toHaveBeenCalledOnce(); - const { identifiers } = mockSendEvents.mock.calls[0][0]; - expect(identifiers).toEqual(new Map([['vuid', 'vuid_a']])); + expect(mockSendEvents).not.toHaveBeenCalled(); }); it('should reject onRunning() if stopped in new state', async () => { diff --git a/lib/odp/odp_manager.ts b/lib/odp/odp_manager.ts index 7525d0efb..2eb9c2e16 100644 --- a/lib/odp/odp_manager.ts +++ b/lib/odp/odp_manager.ts @@ -15,7 +15,7 @@ */ import { v4 as uuidV4} from 'uuid'; -import { LoggerFacade } from '../logging/logger'; +import { LoggerFacade, LogLevel } from '../logging/logger'; import { OdpIntegrationConfig, odpIntegrationsAreEqual } from './odp_config'; import { OdpEventManager } from './event_manager/odp_event_manager'; @@ -32,6 +32,7 @@ import { Maybe } from '../utils/type'; import { sprintf } from '../utils/fns'; import { SERVICE_STOPPED_BEFORE_RUNNING } from '../service'; import { Platform } from '../platform_support'; +import { ODP_IDENTIFY_NOT_DISPATCHED } from '../message/log_message'; export interface OdpManager extends Service { updateConfig(odpIntegrationConfig: OdpIntegrationConfig): boolean; @@ -212,7 +213,7 @@ export class DefaultOdpManager extends BaseService implements OdpManager { identifyUser(userId: string, vuid?: string): void { const identifiers = new Map(); - + let finalUserId: Maybe = userId; let finalVuid: Maybe = vuid; @@ -229,6 +230,13 @@ export class DefaultOdpManager extends BaseService implements OdpManager { identifiers.set(ODP_USER_KEY.FS_USER_ID, finalUserId); } + // Identify requires 2+ identifiers to link (e.g., vuid + fs_user_id). + // A single identifier has no cross-reference value and generates unnecessary traffic. + if (identifiers.size < 2) { + this.logger?.debug(ODP_IDENTIFY_NOT_DISPATCHED); + return; + } + const event = new OdpEvent(ODP_DEFAULT_EVENT_TYPE, ODP_EVENT_ACTION.IDENTIFIED, identifiers); this.sendEvent(event); }