import Types, { EventType, getMessageTypeFromEventType, getIdentityTypeFromBatchKey, } from './types'; import { inArray, valueof } from './utils'; import KitFilterHelper from './kitFilterHelper'; import * as EventsApi from '@mparticle/event-models'; import { IKitFilterSettings } from './configAPIClient'; import { getEventNameFromBatchEvent, getEventCategoryFromBatchEvent, } from './sdkToEventsApiConverter'; type ForwarderFilterConfig = Pick< IKitFilterSettings, | 'eventNameFilters' | 'eventTypeFilters' | 'screenNameFilters' | 'screenAttributeFilters' | 'attributeFilters' | 'userIdentityFilters' | 'filteringEventAttributeValue' >; const FORWARDING_RULE_MESSAGE_TYPES: number[] = [ Types.MessageType.PageEvent, Types.MessageType.PageView, Types.MessageType.Commerce, ]; function inFilteredList( filterList: number[] | undefined, hash: number ): boolean { if (filterList && filterList.length) { return inArray(filterList, hash); } return false; } export function isBlockedByForwardingRule( messageType: number, attributes: Record | null, forwarder: ForwarderFilterConfig ): boolean { if ( !FORWARDING_RULE_MESSAGE_TYPES.includes(messageType) || !forwarder.filteringEventAttributeValue || !forwarder.filteringEventAttributeValue.eventAttributeName || !forwarder.filteringEventAttributeValue.eventAttributeValue ) { return false; } let foundProp: { name: string; value: string } | null = null; if (attributes) { for (const prop in attributes) { if (attributes.hasOwnProperty(prop)) { const hashedName = KitFilterHelper.hashAttributeConditionalForwarding( prop ); if ( hashedName === forwarder.filteringEventAttributeValue.eventAttributeName ) { foundProp = { name: hashedName, value: KitFilterHelper.hashAttributeConditionalForwarding( attributes[prop] as string ), }; break; } } } } const isMatch = foundProp !== null && foundProp.value === forwarder.filteringEventAttributeValue.eventAttributeValue; const shouldInclude = forwarder.filteringEventAttributeValue.includeOnMatch === true ? isMatch : !isMatch; return !shouldInclude; } export function isBlockedByEventFilter( messageType: number, hashedEventName: number, hashedEventType: number, forwarder: ForwarderFilterConfig ): boolean { if ( messageType === Types.MessageType.PageEvent && (inFilteredList(forwarder.eventNameFilters, hashedEventName) || inFilteredList(forwarder.eventTypeFilters, hashedEventType)) ) { return true; } else if ( messageType === Types.MessageType.Commerce && inFilteredList(forwarder.eventTypeFilters, hashedEventType) ) { return true; } else if ( messageType === Types.MessageType.PageView && inFilteredList(forwarder.screenNameFilters, hashedEventName) ) { return true; } return false; } export function filterEventAttributes( messageType: number, eventCategory: number, eventName: string, attributes: Record | null, forwarder: ForwarderFilterConfig ): Record | null { if (!attributes) { return attributes; } let filterList: number[] | undefined; if (messageType === Types.MessageType.PageEvent) { filterList = forwarder.attributeFilters; } else if (messageType === Types.MessageType.PageView) { filterList = forwarder.screenAttributeFilters; } if (!filterList) { return attributes; } const filtered: Record = {}; for (const attrName in attributes) { if (attributes.hasOwnProperty(attrName)) { const hash = KitFilterHelper.hashEventAttributeKey( eventCategory as valueof, eventName, attrName ); if (!inArray(filterList, hash)) { filtered[attrName] = attributes[attrName]; } } } return filtered; } export function filterUserIdentities( userIdentities: Array<{ Type: number }> | undefined, filterList: number[] ): Array<{ Type: number }> { if (!userIdentities || !userIdentities.length) { return userIdentities || []; } return userIdentities.filter(function(userIdentity) { return !inArray( filterList, KitFilterHelper.hashUserIdentity(userIdentity.Type) ); }); } export function isBatchEventAllowed( batchEvent: EventsApi.BaseEvent, forwarder: ForwarderFilterConfig ): boolean { if (!batchEvent || !(batchEvent as any).data) { return true; } const messageType = getMessageTypeFromEventType( (batchEvent as any).event_type ); const eventName = getEventNameFromBatchEvent(batchEvent); const eventCategory = getEventCategoryFromBatchEvent(batchEvent); if ( isBlockedByForwardingRule( messageType, (batchEvent as any).data.custom_attributes, forwarder ) ) { return false; } const hashedEventName = KitFilterHelper.hashEventName( eventName, eventCategory as valueof ); const hashedEventType = KitFilterHelper.hashEventType( eventCategory as valueof ); return !isBlockedByEventFilter( messageType, hashedEventName, hashedEventType, forwarder ); } export function filterBatchEventAttributes( batchEvent: EventsApi.BaseEvent, forwarder: ForwarderFilterConfig ): void { if (!batchEvent || !(batchEvent as any).data) { return; } const messageType = getMessageTypeFromEventType( (batchEvent as any).event_type ); const eventName = getEventNameFromBatchEvent(batchEvent); const eventCategory = getEventCategoryFromBatchEvent(batchEvent); (batchEvent as any).data.custom_attributes = filterEventAttributes( messageType, eventCategory, eventName, (batchEvent as any).data.custom_attributes, forwarder ); } export function filterBatchIdentities( userIdentities: Record | undefined, filterList: number[] | undefined ): Record | undefined { if (!userIdentities || !filterList) { return userIdentities; } const filtered: Record = {}; for (const key in userIdentities) { if (userIdentities.hasOwnProperty(key)) { const identityType = getIdentityTypeFromBatchKey(key); if ( identityType === -1 || !inArray(filterList, identityType) ) { filtered[key] = userIdentities[key]; } } } return filtered; }