mirror of
https://github.com/langgenius/dify.git
synced 2026-04-18 04:16:28 +08:00
Add Amplitude analytics integration and tracking (#27890)
- Introduced AmplitudeProvider component for initializing Amplitude analytics. - Integrated user tracking in AppContextProvider to report user and workspace information. - Added event tracking for workflow log filter selections. - Updated package.json and pnpm-lock.yaml to include @amplitude/unified dependency.
This commit is contained in:
parent
898e65d645
commit
d960d3ee3e
@ -8,6 +8,7 @@ import quarterOfYear from 'dayjs/plugin/quarterOfYear'
|
|||||||
import type { QueryParam } from './index'
|
import type { QueryParam } from './index'
|
||||||
import Chip from '@/app/components/base/chip'
|
import Chip from '@/app/components/base/chip'
|
||||||
import Input from '@/app/components/base/input'
|
import Input from '@/app/components/base/input'
|
||||||
|
import { trackEvent } from '../../base/amplitude/utils'
|
||||||
dayjs.extend(quarterOfYear)
|
dayjs.extend(quarterOfYear)
|
||||||
|
|
||||||
const today = dayjs()
|
const today = dayjs()
|
||||||
@ -37,6 +38,9 @@ const Filter: FC<IFilterProps> = ({ queryParams, setQueryParams }: IFilterProps)
|
|||||||
value={queryParams.status || 'all'}
|
value={queryParams.status || 'all'}
|
||||||
onSelect={(item) => {
|
onSelect={(item) => {
|
||||||
setQueryParams({ ...queryParams, status: item.value as string })
|
setQueryParams({ ...queryParams, status: item.value as string })
|
||||||
|
trackEvent('workflow_log_filter_status_selected', {
|
||||||
|
workflow_log_filter_status: item.value as string,
|
||||||
|
})
|
||||||
}}
|
}}
|
||||||
onClear={() => setQueryParams({ ...queryParams, status: 'all' })}
|
onClear={() => setQueryParams({ ...queryParams, status: 'all' })}
|
||||||
items={[{ value: 'all', name: 'All' },
|
items={[{ value: 'all', name: 'All' },
|
||||||
|
|||||||
@ -14,14 +14,6 @@ export const trackEvent = (eventName: string, eventProperties?: Record<string, a
|
|||||||
* @param userId User ID
|
* @param userId User ID
|
||||||
*/
|
*/
|
||||||
export const setUserId = (userId: string) => {
|
export const setUserId = (userId: string) => {
|
||||||
if (!userId) {
|
|
||||||
console.warn('[Amplitude] ⚠️ Cannot set empty user ID')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (process.env.NODE_ENV === 'development')
|
|
||||||
console.log('[Amplitude] 👤 Setting User ID:', userId)
|
|
||||||
|
|
||||||
amplitude.setUserId(userId)
|
amplitude.setUserId(userId)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,37 +22,11 @@ export const setUserId = (userId: string) => {
|
|||||||
* @param properties User properties
|
* @param properties User properties
|
||||||
*/
|
*/
|
||||||
export const setUserProperties = (properties: Record<string, any>) => {
|
export const setUserProperties = (properties: Record<string, any>) => {
|
||||||
// Filter out undefined and null values
|
|
||||||
const validProperties = Object.entries(properties).reduce((acc, [key, value]) => {
|
|
||||||
if (value !== undefined && value !== null)
|
|
||||||
acc[key] = value
|
|
||||||
|
|
||||||
return acc
|
|
||||||
}, {} as Record<string, any>)
|
|
||||||
|
|
||||||
if (Object.keys(validProperties).length === 0) {
|
|
||||||
if (process.env.NODE_ENV === 'development')
|
|
||||||
console.warn('[Amplitude] ⚠️ No valid properties to set')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (process.env.NODE_ENV === 'development')
|
|
||||||
console.log('[Amplitude] 📊 Setting user properties:', validProperties)
|
|
||||||
|
|
||||||
const identifyEvent = new amplitude.Identify()
|
const identifyEvent = new amplitude.Identify()
|
||||||
Object.entries(validProperties).forEach(([key, value]) => {
|
Object.entries(properties).forEach(([key, value]) => {
|
||||||
identifyEvent.set(key, value)
|
identifyEvent.set(key, value)
|
||||||
})
|
})
|
||||||
|
amplitude.identify(identifyEvent)
|
||||||
const result = amplitude.identify(identifyEvent)
|
|
||||||
|
|
||||||
// Log the result in development
|
|
||||||
result.promise.then(() => {
|
|
||||||
if (process.env.NODE_ENV === 'development')
|
|
||||||
console.log('[Amplitude] ✅ User properties set successfully')
|
|
||||||
}).catch((err) => {
|
|
||||||
console.error('[Amplitude] ❌ Failed to set user properties:', err)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -12,6 +12,7 @@ import { setZendeskConversationFields } from '@/app/components/base/zendesk/util
|
|||||||
import { ZENDESK_FIELD_IDS } from '@/config'
|
import { ZENDESK_FIELD_IDS } from '@/config'
|
||||||
import { setUserId, setUserProperties } from '@/app/components/base/amplitude'
|
import { setUserId, setUserProperties } from '@/app/components/base/amplitude'
|
||||||
import { useGlobalPublicStore } from './global-public-context'
|
import { useGlobalPublicStore } from './global-public-context'
|
||||||
|
import { setUserId, setUserProperties } from '@/app/components/base/amplitude'
|
||||||
|
|
||||||
export type AppContextValue = {
|
export type AppContextValue = {
|
||||||
userProfile: UserProfileResponse
|
userProfile: UserProfileResponse
|
||||||
@ -163,41 +164,28 @@ export const AppContextProvider: FC<AppContextProviderProps> = ({ children }) =>
|
|||||||
// #region Amplitude user tracking
|
// #region Amplitude user tracking
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// Report user info to Amplitude when loaded
|
// Report user info to Amplitude when loaded
|
||||||
if (!userProfile?.id)
|
if (userProfile?.id) {
|
||||||
return
|
setUserId(userProfile.id)
|
||||||
|
setUserProperties({
|
||||||
// Step 1: Set User ID first
|
email: userProfile.email,
|
||||||
setUserId(userProfile.id)
|
name: userProfile.name,
|
||||||
|
has_password: userProfile.is_password_set,
|
||||||
// Step 2: Set user properties
|
})
|
||||||
const userProperties: Record<string, any> = {
|
|
||||||
email: userProfile.email,
|
|
||||||
name: userProfile.name,
|
|
||||||
has_password: userProfile.is_password_set,
|
|
||||||
}
|
}
|
||||||
|
}, [userProfile?.id, userProfile?.email, userProfile?.name, userProfile?.is_password_set])
|
||||||
|
|
||||||
// Step 3: Add workspace properties if available
|
useEffect(() => {
|
||||||
if (currentWorkspace?.id) {
|
// Report workspace info to Amplitude when loaded
|
||||||
userProperties.workspace_id = currentWorkspace.id
|
if (currentWorkspace?.id && userProfile?.id) {
|
||||||
userProperties.workspace_name = currentWorkspace.name
|
setUserProperties({
|
||||||
userProperties.workspace_plan = currentWorkspace.plan
|
workspace_id: currentWorkspace.id,
|
||||||
userProperties.workspace_status = currentWorkspace.status
|
workspace_name: currentWorkspace.name,
|
||||||
userProperties.workspace_role = currentWorkspace.role
|
workspace_plan: currentWorkspace.plan,
|
||||||
|
workspace_status: currentWorkspace.status,
|
||||||
|
workspace_role: currentWorkspace.role,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
}, [currentWorkspace?.id, currentWorkspace?.name, currentWorkspace?.plan, currentWorkspace?.status, currentWorkspace?.role, userProfile?.id])
|
||||||
// Set all properties at once
|
|
||||||
setUserProperties(userProperties)
|
|
||||||
}, [
|
|
||||||
userProfile?.id,
|
|
||||||
userProfile?.email,
|
|
||||||
userProfile?.name,
|
|
||||||
userProfile?.is_password_set,
|
|
||||||
currentWorkspace?.id,
|
|
||||||
currentWorkspace?.name,
|
|
||||||
currentWorkspace?.plan,
|
|
||||||
currentWorkspace?.status,
|
|
||||||
currentWorkspace?.role,
|
|
||||||
])
|
|
||||||
// #endregion Amplitude user tracking
|
// #endregion Amplitude user tracking
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
175
web/pnpm-lock.yaml
generated
175
web/pnpm-lock.yaml
generated
@ -8765,6 +8765,181 @@ snapshots:
|
|||||||
|
|
||||||
'@antfu/eslint-config@5.4.1(@eslint-react/eslint-plugin@1.53.1(eslint@9.38.0(jiti@1.21.7))(ts-api-utils@2.1.0(typescript@5.9.3))(typescript@5.9.3))(@next/eslint-plugin-next@15.5.4)(@vue/compiler-sfc@3.5.17)(eslint-plugin-react-hooks@5.2.0(eslint@9.38.0(jiti@1.21.7)))(eslint-plugin-react-refresh@0.4.24(eslint@9.38.0(jiti@1.21.7)))(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3)':
|
'@antfu/eslint-config@5.4.1(@eslint-react/eslint-plugin@1.53.1(eslint@9.38.0(jiti@1.21.7))(ts-api-utils@2.1.0(typescript@5.9.3))(typescript@5.9.3))(@next/eslint-plugin-next@15.5.4)(@vue/compiler-sfc@3.5.17)(eslint-plugin-react-hooks@5.2.0(eslint@9.38.0(jiti@1.21.7)))(eslint-plugin-react-refresh@0.4.24(eslint@9.38.0(jiti@1.21.7)))(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3)':
|
||||||
'@antfu/eslint-config@5.4.1(@eslint-react/eslint-plugin@1.53.1(eslint@9.38.0(jiti@1.21.7))(ts-api-utils@2.1.0(typescript@5.9.3))(typescript@5.9.3))(@next/eslint-plugin-next@15.5.4)(@vue/compiler-sfc@3.5.22)(eslint-plugin-react-hooks@5.2.0(eslint@9.38.0(jiti@1.21.7)))(eslint-plugin-react-refresh@0.4.24(eslint@9.38.0(jiti@1.21.7)))(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3)':
|
'@antfu/eslint-config@5.4.1(@eslint-react/eslint-plugin@1.53.1(eslint@9.38.0(jiti@1.21.7))(ts-api-utils@2.1.0(typescript@5.9.3))(typescript@5.9.3))(@next/eslint-plugin-next@15.5.4)(@vue/compiler-sfc@3.5.22)(eslint-plugin-react-hooks@5.2.0(eslint@9.38.0(jiti@1.21.7)))(eslint-plugin-react-refresh@0.4.24(eslint@9.38.0(jiti@1.21.7)))(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3)':
|
||||||
|
'@amplitude/analytics-browser@2.30.1':
|
||||||
|
dependencies:
|
||||||
|
'@amplitude/analytics-core': 2.31.1
|
||||||
|
'@amplitude/plugin-autocapture-browser': 1.17.1
|
||||||
|
'@amplitude/plugin-network-capture-browser': 1.6.13
|
||||||
|
'@amplitude/plugin-page-url-enrichment-browser': 0.5.2
|
||||||
|
'@amplitude/plugin-page-view-tracking-browser': 2.5.7
|
||||||
|
'@amplitude/plugin-web-vitals-browser': 0.1.0-frustrationanalytics.0
|
||||||
|
tslib: 2.8.1
|
||||||
|
|
||||||
|
'@amplitude/analytics-client-common@2.4.12':
|
||||||
|
dependencies:
|
||||||
|
'@amplitude/analytics-connector': 1.6.4
|
||||||
|
'@amplitude/analytics-core': 2.31.1
|
||||||
|
'@amplitude/analytics-types': 2.11.0
|
||||||
|
tslib: 2.8.1
|
||||||
|
|
||||||
|
'@amplitude/analytics-connector@1.6.4': {}
|
||||||
|
|
||||||
|
'@amplitude/analytics-core@2.31.1':
|
||||||
|
dependencies:
|
||||||
|
'@amplitude/analytics-connector': 1.6.4
|
||||||
|
tslib: 2.8.1
|
||||||
|
|
||||||
|
'@amplitude/analytics-types@1.4.0': {}
|
||||||
|
|
||||||
|
'@amplitude/analytics-types@2.11.0': {}
|
||||||
|
|
||||||
|
'@amplitude/engagement-browser@1.0.5':
|
||||||
|
dependencies:
|
||||||
|
'@amplitude/analytics-types': 1.4.0
|
||||||
|
|
||||||
|
'@amplitude/experiment-core@0.11.1':
|
||||||
|
dependencies:
|
||||||
|
js-base64: 3.7.8
|
||||||
|
|
||||||
|
'@amplitude/experiment-core@0.7.2':
|
||||||
|
dependencies:
|
||||||
|
js-base64: 3.7.8
|
||||||
|
|
||||||
|
'@amplitude/experiment-js-client@1.18.0':
|
||||||
|
dependencies:
|
||||||
|
'@amplitude/analytics-connector': 1.6.4
|
||||||
|
'@amplitude/experiment-core': 0.11.1
|
||||||
|
'@amplitude/ua-parser-js': 0.7.33
|
||||||
|
base64-js: 1.5.1
|
||||||
|
unfetch: 4.1.0
|
||||||
|
|
||||||
|
'@amplitude/plugin-autocapture-browser@1.17.1':
|
||||||
|
dependencies:
|
||||||
|
'@amplitude/analytics-core': 2.31.1
|
||||||
|
rxjs: 7.8.2
|
||||||
|
tslib: 2.8.1
|
||||||
|
|
||||||
|
'@amplitude/plugin-experiment-browser@1.0.0-beta.0':
|
||||||
|
dependencies:
|
||||||
|
'@amplitude/analytics-core': 2.31.1
|
||||||
|
'@amplitude/experiment-js-client': 1.18.0
|
||||||
|
|
||||||
|
'@amplitude/plugin-network-capture-browser@1.6.13':
|
||||||
|
dependencies:
|
||||||
|
'@amplitude/analytics-core': 2.31.1
|
||||||
|
rxjs: 7.8.2
|
||||||
|
tslib: 2.8.1
|
||||||
|
|
||||||
|
'@amplitude/plugin-page-url-enrichment-browser@0.5.2':
|
||||||
|
dependencies:
|
||||||
|
'@amplitude/analytics-core': 2.31.1
|
||||||
|
tslib: 2.8.1
|
||||||
|
|
||||||
|
'@amplitude/plugin-page-view-tracking-browser@2.5.7':
|
||||||
|
dependencies:
|
||||||
|
'@amplitude/analytics-core': 2.31.1
|
||||||
|
tslib: 2.8.1
|
||||||
|
|
||||||
|
'@amplitude/plugin-session-replay-browser@1.23.2(@amplitude/rrweb@2.0.0-alpha.33)(rollup@2.79.2)':
|
||||||
|
dependencies:
|
||||||
|
'@amplitude/analytics-client-common': 2.4.12
|
||||||
|
'@amplitude/analytics-core': 2.31.1
|
||||||
|
'@amplitude/analytics-types': 2.11.0
|
||||||
|
'@amplitude/session-replay-browser': 1.29.4(@amplitude/rrweb@2.0.0-alpha.33)(rollup@2.79.2)
|
||||||
|
idb-keyval: 6.2.2
|
||||||
|
tslib: 2.8.1
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- '@amplitude/rrweb'
|
||||||
|
- rollup
|
||||||
|
|
||||||
|
'@amplitude/plugin-web-vitals-browser@0.1.0-frustrationanalytics.0':
|
||||||
|
dependencies:
|
||||||
|
'@amplitude/analytics-core': 2.31.1
|
||||||
|
rxjs: 7.8.2
|
||||||
|
tslib: 2.8.1
|
||||||
|
web-vitals: 5.1.0
|
||||||
|
|
||||||
|
'@amplitude/rrdom@2.0.0-alpha.33':
|
||||||
|
dependencies:
|
||||||
|
'@amplitude/rrweb-snapshot': 2.0.0-alpha.33
|
||||||
|
|
||||||
|
'@amplitude/rrweb-packer@2.0.0-alpha.32':
|
||||||
|
dependencies:
|
||||||
|
'@amplitude/rrweb-types': 2.0.0-alpha.32
|
||||||
|
fflate: 0.4.8
|
||||||
|
|
||||||
|
'@amplitude/rrweb-plugin-console-record@2.0.0-alpha.32(@amplitude/rrweb@2.0.0-alpha.33)':
|
||||||
|
dependencies:
|
||||||
|
'@amplitude/rrweb': 2.0.0-alpha.33
|
||||||
|
|
||||||
|
'@amplitude/rrweb-record@2.0.0-alpha.32':
|
||||||
|
dependencies:
|
||||||
|
'@amplitude/rrweb': 2.0.0-alpha.33
|
||||||
|
'@amplitude/rrweb-types': 2.0.0-alpha.32
|
||||||
|
|
||||||
|
'@amplitude/rrweb-snapshot@2.0.0-alpha.33':
|
||||||
|
dependencies:
|
||||||
|
postcss: 8.5.6
|
||||||
|
|
||||||
|
'@amplitude/rrweb-types@2.0.0-alpha.32': {}
|
||||||
|
|
||||||
|
'@amplitude/rrweb-types@2.0.0-alpha.33': {}
|
||||||
|
|
||||||
|
'@amplitude/rrweb-utils@2.0.0-alpha.32': {}
|
||||||
|
|
||||||
|
'@amplitude/rrweb-utils@2.0.0-alpha.33': {}
|
||||||
|
|
||||||
|
'@amplitude/rrweb@2.0.0-alpha.33':
|
||||||
|
dependencies:
|
||||||
|
'@amplitude/rrdom': 2.0.0-alpha.33
|
||||||
|
'@amplitude/rrweb-snapshot': 2.0.0-alpha.33
|
||||||
|
'@amplitude/rrweb-types': 2.0.0-alpha.33
|
||||||
|
'@amplitude/rrweb-utils': 2.0.0-alpha.33
|
||||||
|
'@types/css-font-loading-module': 0.0.7
|
||||||
|
'@xstate/fsm': 1.6.5
|
||||||
|
base64-arraybuffer: 1.0.2
|
||||||
|
mitt: 3.0.1
|
||||||
|
|
||||||
|
'@amplitude/session-replay-browser@1.29.4(@amplitude/rrweb@2.0.0-alpha.33)(rollup@2.79.2)':
|
||||||
|
dependencies:
|
||||||
|
'@amplitude/analytics-client-common': 2.4.12
|
||||||
|
'@amplitude/analytics-core': 2.31.1
|
||||||
|
'@amplitude/analytics-types': 2.11.0
|
||||||
|
'@amplitude/rrweb-packer': 2.0.0-alpha.32
|
||||||
|
'@amplitude/rrweb-plugin-console-record': 2.0.0-alpha.32(@amplitude/rrweb@2.0.0-alpha.33)
|
||||||
|
'@amplitude/rrweb-record': 2.0.0-alpha.32
|
||||||
|
'@amplitude/rrweb-types': 2.0.0-alpha.32
|
||||||
|
'@amplitude/rrweb-utils': 2.0.0-alpha.32
|
||||||
|
'@amplitude/targeting': 0.2.0
|
||||||
|
'@rollup/plugin-replace': 6.0.3(rollup@2.79.2)
|
||||||
|
idb: 8.0.0
|
||||||
|
tslib: 2.8.1
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- '@amplitude/rrweb'
|
||||||
|
- rollup
|
||||||
|
|
||||||
|
'@amplitude/targeting@0.2.0':
|
||||||
|
dependencies:
|
||||||
|
'@amplitude/analytics-client-common': 2.4.12
|
||||||
|
'@amplitude/analytics-core': 2.31.1
|
||||||
|
'@amplitude/analytics-types': 2.11.0
|
||||||
|
'@amplitude/experiment-core': 0.7.2
|
||||||
|
idb: 8.0.0
|
||||||
|
tslib: 2.8.1
|
||||||
|
|
||||||
|
'@amplitude/ua-parser-js@0.7.33': {}
|
||||||
|
|
||||||
|
'@amplitude/unified@1.0.0-beta.9(@amplitude/rrweb@2.0.0-alpha.33)(rollup@2.79.2)':
|
||||||
|
dependencies:
|
||||||
|
'@amplitude/analytics-browser': 2.30.1
|
||||||
|
'@amplitude/engagement-browser': 1.0.5
|
||||||
|
'@amplitude/plugin-experiment-browser': 1.0.0-beta.0
|
||||||
|
'@amplitude/plugin-session-replay-browser': 1.23.2(@amplitude/rrweb@2.0.0-alpha.33)(rollup@2.79.2)
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- '@amplitude/rrweb'
|
||||||
|
- rollup
|
||||||
|
|
||||||
|
'@antfu/eslint-config@5.4.1(@eslint-react/eslint-plugin@1.53.1(eslint@9.38.0(jiti@1.21.7))(ts-api-utils@2.1.0(typescript@5.9.3))(typescript@5.9.3))(@next/eslint-plugin-next@15.5.4)(@vue/compiler-sfc@3.5.17)(eslint-plugin-react-hooks@5.2.0(eslint@9.38.0(jiti@1.21.7)))(eslint-plugin-react-refresh@0.4.24(eslint@9.38.0(jiti@1.21.7)))(eslint@9.38.0(jiti@1.21.7))(typescript@5.9.3)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@antfu/install-pkg': 1.1.0
|
'@antfu/install-pkg': 1.1.0
|
||||||
'@clack/prompts': 0.11.0
|
'@clack/prompts': 0.11.0
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user