[MM-59365] Paid End-User features company metric - "Passive keyword tracking" Telemetry (#28734)
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
038d59560e
Коммит
89c6fbc1e9
@@ -21,7 +21,7 @@ export function shouldTrackPerformance(state = store.getState()) {
|
|||||||
return isDevModeEnabled(state) || isTelemetryEnabled(state);
|
return isDevModeEnabled(state) || isTelemetryEnabled(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function trackEvent(category, event, props) {
|
export function trackEvent(category, event, props = {}) {
|
||||||
const state = store.getState();
|
const state = store.getState();
|
||||||
if (
|
if (
|
||||||
isPerformanceDebuggingEnabled(state) &&
|
isPerformanceDebuggingEnabled(state) &&
|
||||||
@@ -38,7 +38,7 @@ export function trackEvent(category, event, props) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function trackFeatureEvent(featureName, event, props) {
|
export function trackFeatureEvent(featureName, event, props = {}) {
|
||||||
Client4.trackFeatureEvent(featureName, event, props);
|
Client4.trackFeatureEvent(featureName, event, props);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ const GroupOption = (props: Props) => {
|
|||||||
for (const profile of profiles) {
|
for (const profile of profiles) {
|
||||||
addUserProfile(profile);
|
addUserProfile(profile);
|
||||||
}
|
}
|
||||||
trackFeatureEvent(TrackGroupsFeature, TrackInviteGroupEvent, {});
|
trackFeatureEvent(TrackGroupsFeature, TrackInviteGroupEvent);
|
||||||
}, [addUserProfile, profiles]);
|
}, [addUserProfile, profiles]);
|
||||||
|
|
||||||
const onKeyDown = useCallback((e: KeyboardEvent) => {
|
const onKeyDown = useCallback((e: KeyboardEvent) => {
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ export type MarketplaceItemAppProps = {
|
|||||||
installing: boolean;
|
installing: boolean;
|
||||||
error?: string;
|
error?: string;
|
||||||
|
|
||||||
trackEvent: (category: string, event: string, props?: unknown) => void;
|
trackEvent: (category: string, event: string, props?: Record<string, unknown>) => void;
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
installApp: (id: string) => Promise<boolean>;
|
installApp: (id: string) => Promise<boolean>;
|
||||||
|
|||||||
@@ -239,7 +239,7 @@ export type MarketplaceItemPluginProps = {
|
|||||||
pluginStatus?: PluginStatusRedux;
|
pluginStatus?: PluginStatusRedux;
|
||||||
error?: string;
|
error?: string;
|
||||||
isDefaultMarketplace: boolean;
|
isDefaultMarketplace: boolean;
|
||||||
trackEvent: (category: string, event: string, props?: unknown) => void;
|
trackEvent: (category: string, event: string, props?: Record<string, unknown>) => void;
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
installPlugin: (id: string) => void;
|
installPlugin: (id: string) => void;
|
||||||
|
|||||||
@@ -14,6 +14,10 @@ import {LightbulbOutlineIcon} from '@mattermost/compass-icons/components';
|
|||||||
import type {PreferencesType} from '@mattermost/types/preferences';
|
import type {PreferencesType} from '@mattermost/types/preferences';
|
||||||
import type {UserNotifyProps, UserProfile} from '@mattermost/types/users';
|
import type {UserNotifyProps, UserProfile} from '@mattermost/types/users';
|
||||||
|
|
||||||
|
import {TrackPassiveKeywordsFeature, TrackPassiveKeywordsEvent} from 'mattermost-redux/constants/telemetry';
|
||||||
|
|
||||||
|
import {trackFeatureEvent} from 'actions/telemetry_actions.jsx';
|
||||||
|
|
||||||
import ExternalLink from 'components/external_link';
|
import ExternalLink from 'components/external_link';
|
||||||
import SettingItem from 'components/setting_item';
|
import SettingItem from 'components/setting_item';
|
||||||
import SettingItemMax from 'components/setting_item_max';
|
import SettingItemMax from 'components/setting_item_max';
|
||||||
@@ -283,6 +287,9 @@ class NotificationsTab extends React.PureComponent<Props, State> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
data.highlight_keys = highlightKeys.join(',');
|
data.highlight_keys = highlightKeys.join(',');
|
||||||
|
if (this.props.user.notify_props?.highlight_keys !== data.highlight_keys && data.highlight_keys.length > 0) {
|
||||||
|
trackFeatureEvent(TrackPassiveKeywordsFeature, TrackPassiveKeywordsEvent);
|
||||||
|
}
|
||||||
|
|
||||||
this.setState({isSaving: true});
|
this.setState({isSaving: true});
|
||||||
stopTryNotificationRing();
|
stopTryNotificationRing();
|
||||||
|
|||||||
@@ -7,21 +7,13 @@ import * as rudderAnalytics from 'rudder-sdk-js';
|
|||||||
|
|
||||||
import type {TelemetryHandler} from '@mattermost/client';
|
import type {TelemetryHandler} from '@mattermost/client';
|
||||||
|
|
||||||
import {TrackMiscCategory, TrackActionCategory, TrackEnterpriseSKU, TrackProfessionalSKU, TrackInviteGroupEvent} from 'mattermost-redux/constants/telemetry';
|
import {TrackMiscCategory, eventCategory, eventSKUs} from 'mattermost-redux/constants/telemetry';
|
||||||
import {isSystemAdmin} from 'mattermost-redux/utils/user_utils';
|
import {isSystemAdmin} from 'mattermost-redux/utils/user_utils';
|
||||||
|
|
||||||
export {rudderAnalytics};
|
export {rudderAnalytics};
|
||||||
|
|
||||||
const eventSKUs: {[event: string]: string[]} = {
|
|
||||||
[TrackInviteGroupEvent]: [TrackProfessionalSKU, TrackEnterpriseSKU],
|
|
||||||
};
|
|
||||||
|
|
||||||
const eventCategory: {[event: string]: string} = {
|
|
||||||
[TrackInviteGroupEvent]: TrackActionCategory,
|
|
||||||
};
|
|
||||||
|
|
||||||
export class RudderTelemetryHandler implements TelemetryHandler {
|
export class RudderTelemetryHandler implements TelemetryHandler {
|
||||||
trackEvent(userId: string, userRoles: string, category: string, event: string, props?: any) {
|
trackEvent(userId: string, userRoles: string, category: string, event: string, props: Record<string, unknown> = {}) {
|
||||||
const properties = Object.assign({
|
const properties = Object.assign({
|
||||||
category,
|
category,
|
||||||
type: event,
|
type: event,
|
||||||
@@ -45,13 +37,14 @@ export class RudderTelemetryHandler implements TelemetryHandler {
|
|||||||
rudderAnalytics.track('event', properties, options);
|
rudderAnalytics.track('event', properties, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
trackFeatureEvent(userId: string, userRoles: string, featureName: string, event: string, props?: any) {
|
trackFeatureEvent(userId: string, userRoles: string, featureName: string, event: string, props: Record<string, unknown> = {}) {
|
||||||
const properties = Object.assign({
|
const properties = Object.assign({
|
||||||
category: getEventCategory(event),
|
category: getEventCategory(event),
|
||||||
type: event,
|
type: event,
|
||||||
user_actual_id: userId,
|
user_actual_id: userId,
|
||||||
user_actual_role: getActualRoles(userRoles),
|
user_actual_role: getActualRoles(userRoles),
|
||||||
}, props);
|
}, props);
|
||||||
|
|
||||||
const options = {
|
const options = {
|
||||||
context: {
|
context: {
|
||||||
feature: {
|
feature: {
|
||||||
@@ -93,19 +86,23 @@ function getActualRoles(userRoles: string) {
|
|||||||
|
|
||||||
function getSKUs(eventName: string) {
|
function getSKUs(eventName: string) {
|
||||||
const skus: string[] | undefined = eventSKUs[eventName];
|
const skus: string[] | undefined = eventSKUs[eventName];
|
||||||
|
|
||||||
if (skus === undefined) {
|
if (skus === undefined) {
|
||||||
// Next line is to be aware if you've forgotten to add a SKU, add an empty array for Team edition
|
// Next line is to be aware if you've forgotten to add a SKU, add an empty array for Team edition
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
console.warn(`Event ${eventName} has no SKUs attached`);
|
console.warn(`Event ${eventName} has no SKUs attached`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return skus ?? [];
|
return skus ?? [];
|
||||||
}
|
}
|
||||||
|
|
||||||
function getEventCategory(eventName: string) {
|
function getEventCategory(eventName: string) {
|
||||||
const category: string | undefined = eventCategory[eventName];
|
const category: string | undefined = eventCategory[eventName];
|
||||||
|
|
||||||
if (category === undefined) {
|
if (category === undefined) {
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
console.warn(`Event ${eventName} doesn't have a category`);
|
console.warn(`Event ${eventName} doesn't have a category`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return category ?? TrackMiscCategory;
|
return category ?? TrackMiscCategory;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,9 +12,8 @@ import RequestStatus from './request_status';
|
|||||||
import Roles from './roles';
|
import Roles from './roles';
|
||||||
import Stats from './stats';
|
import Stats from './stats';
|
||||||
import Teams from './teams';
|
import Teams from './teams';
|
||||||
import Telemetry from './telemetry';
|
|
||||||
import Threads from './threads';
|
import Threads from './threads';
|
||||||
import Users from './users';
|
import Users from './users';
|
||||||
import WebsocketEvents from './websocket';
|
import WebsocketEvents from './websocket';
|
||||||
|
|
||||||
export {General, Preferences, Posts, Files, RequestStatus, WebsocketEvents, Teams, Stats, Permissions, Emoji, Plugins, Users, Roles, Threads, Telemetry};
|
export {General, Preferences, Posts, Files, RequestStatus, WebsocketEvents, Teams, Stats, Permissions, Emoji, Plugins, Users, Roles, Threads};
|
||||||
|
|||||||
@@ -6,13 +6,23 @@ export const TrackProfessionalSKU = 'professional';
|
|||||||
export const TrackEnterpriseSKU = 'enterprise';
|
export const TrackEnterpriseSKU = 'enterprise';
|
||||||
|
|
||||||
// Features
|
// Features
|
||||||
export const TrackGroupsFeature: string = 'custom_groups';
|
export const TrackGroupsFeature = 'custom_groups';
|
||||||
|
export const TrackPassiveKeywordsFeature = 'passive_keywords';
|
||||||
|
|
||||||
// Events
|
// Events
|
||||||
export const TrackInviteGroupEvent: string = 'invite_group_to_channel';
|
export const TrackInviteGroupEvent = 'invite_group_to_channel';
|
||||||
|
export const TrackPassiveKeywordsEvent = 'update_passive_keywords';
|
||||||
|
|
||||||
// Categories
|
// Categories
|
||||||
export const TrackActionCategory: string = 'action';
|
export const TrackActionCategory = 'action';
|
||||||
export const TrackMiscCategory: string = 'miscellaneous';
|
export const TrackMiscCategory = 'miscellaneous';
|
||||||
|
|
||||||
export default {TrackActionCategory, TrackMiscCategory, TrackInviteGroupEvent, TrackGroupsFeature, TrackEnterpriseSKU, TrackProfessionalSKU};
|
export const eventSKUs: {[event: string]: string[]} = {
|
||||||
|
[TrackInviteGroupEvent]: [TrackProfessionalSKU, TrackEnterpriseSKU],
|
||||||
|
[TrackPassiveKeywordsEvent]: [TrackProfessionalSKU, TrackEnterpriseSKU],
|
||||||
|
};
|
||||||
|
|
||||||
|
export const eventCategory: {[event: string]: string} = {
|
||||||
|
[TrackInviteGroupEvent]: TrackActionCategory,
|
||||||
|
[TrackPassiveKeywordsEvent]: TrackActionCategory,
|
||||||
|
};
|
||||||
|
|||||||
@@ -4327,7 +4327,8 @@ export default class Client4 {
|
|||||||
this.telemetryHandler.trackEvent(this.userId, this.userRoles, category, event, props);
|
this.telemetryHandler.trackEvent(this.userId, this.userRoles, category, event, props);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
trackFeatureEvent(featureName: string, event: string, props?: any) {
|
|
||||||
|
trackFeatureEvent(featureName: string, event: string, props: Record<string, unknown> = {}) {
|
||||||
if (this.telemetryHandler) {
|
if (this.telemetryHandler) {
|
||||||
this.telemetryHandler.trackFeatureEvent(this.userId, this.userRoles, featureName, event, props);
|
this.telemetryHandler.trackFeatureEvent(this.userId, this.userRoles, featureName, event, props);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
// See LICENSE.txt for license information.
|
// See LICENSE.txt for license information.
|
||||||
|
|
||||||
export interface TelemetryHandler {
|
export interface TelemetryHandler {
|
||||||
trackEvent: (userId: string, userRoles: string, category: string, event: string, props?: any) => void;
|
trackEvent: (userId: string, userRoles: string, category: string, event: string, props?: Record<string, unknown>) => void;
|
||||||
trackFeatureEvent: (userId: string, userRoles: string, featureName: string, event: string, props?: any) => void;
|
trackFeatureEvent: (userId: string, userRoles: string, featureName: string, event: string, props?: Record<string, unknown>) => void;
|
||||||
pageVisited: (userId: string, userRoles: string, category: string, name: string) => void;
|
pageVisited: (userId: string, userRoles: string, category: string, name: string) => void;
|
||||||
}
|
}
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user