Amplitude使用记录
初始化
import amplitude from 'amplitude-js';
import { result } from 'lodash';
import { formatDateTime } from './globalMethods';// 从默认导出中获取类型和类
type AmplitudeClient = amplitude.AmplitudeClient;
type Identify = amplitude.Identify;
type Revenue = amplitude.Revenue;
type AmplitudeOptions = typeof amplitude.options;
// 扩展 Navigator 接口以支持旧版网络信息属性
interface Navigator {mozConnection?: NetworkInformation;webkitConnection?: NetworkInformation;
}// 扩展网络信息相关类型定义
interface NetworkInformation {type?: string;effectiveType?: '2g' | '3g' | '4g' | '5g';downlink?: number;
}// 扩展 Navigator 接口,明确包含所有可能的网络信息属性
interface ExtendedNavigator extends Navigator {connection?: NetworkInformation;mozConnection?: NetworkInformation;webkitConnection?: NetworkInformation;
}
/*** 事件属性类型定义* 支持字符串、数字、布尔值、基础类型数组及嵌套对象*/
export type EventProperties = Record<string,string | number | boolean | Array<string | number> | Record<string, any>
>;/*** 用户属性类型定义* 支持基础类型、日期对象及基础类型数组*/
export type UserProperties = Record<string,string | number | boolean | Date | Array<string | number>
>;/** 内部状态 - 标记是否已初始化 */
let isInitialized = false;/** 内部状态 - 存储Amplitude实例 */
let instance: AmplitudeClient | null = null;/*** 初始化Amplitude SDK* @param apiKey - 从Amplitude项目获取的API密钥(必填)* @param options - 初始化配置选项(可选)*/
export const initializeAmplitude = (options?: AmplitudeOptions
) => {if (isInitialized) {console.warn('Amplitude已初始化,无需重复调用');return;}// 创建实例并初始化instance = amplitude.getInstance();const apiKey = process.env.REACT_APP_AMPLITUDE_API_KEY;instance.init(apiKey, null, {// 默认配置batchEvents: true,storage: 'localStorage', // 缓存方式trackingOptions: {ip_address: false, // 不收集IP(隐私合规)},secureCookie: true, // 仅HTTPS传输CookieserverZone: 'EU', // 欧洲服务器// 合并用户传入的配置(覆盖默认值)...options});isInitialized = true;initUserInfo()
};/*** 初始化用户信息*/
const initUserInfo = () => {const userInfo = JSON.parse(localStorage.getItem('user')) || {}if (!userInfo?.is_track) {// 不跟踪setAmplitudeTrackingStatus(true);return;}setAmplitudeTrackingStatus(false);setAmplitudeUserId(userInfo.id);setAmplitudeUserProperties({user_id: userInfo.id,username: userInfo.username,role: userInfo.role,organization: userInfo?.unique_data || null,research_direction: userInfo?.research_fields || null,});
};/*** 跟踪用户行为事件* @param eventName - 事件名称(必填)* @param properties - 事件属性(可选)* @param callback - 回调函数(可选)*/
export const amplitudeEvent = (eventName: string,properties?: EventProperties,callback?: (code: number) => void
) => {if (!isInitialized || !instance) {console.error('Amplitude未初始化,请先调用initializeAmplitude');return;}instance.logEvent(eventName, properties, callback)
};/*** 设置用户唯一标识* @param userId - 用户唯一ID,登出时可传null*/
export const setAmplitudeUserId = (userId: string | null) => {if (!isInitialized || !instance) {console.error('Amplitude未初始化,请先调用initializeAmplitude');return;}instance.setUserId(userId);
};/*** 获取用户公网IP(通过第三方接口)*/
const getUserIP = async (): Promise<string> => {try {const response = await fetch('https://api.ipify.org?format=json');const data = await response.json();return data.ip || 'unknown';} catch (error) {console.error('获取IP失败:', error);return 'unknown';}
};/*** 兼容旧环境的网络类型检测(修复类型错误版本)* 主要识别:WiFi、5G、4G、3G、2G、Ethernet、No Network*/
const getNetworkType = () => {// 将 navigator 明确断言为扩展类型const nav = navigator as ExtendedNavigator;// 优先获取各种可能的网络连接对象,兼容不同浏览器const connection = nav.connection || nav.mozConnection || nav.webkitConnection;// 不支持任何网络信息 API 的情况if (!connection) {return 'Unknown';}// 处理连接对象的属性访问const conn = connection as {type?: string;effectiveType?: string;downlink?: number;};// 识别核心网络类型if (conn.type === 'wifi') return 'WiFi';if (conn.type === 'ethernet') return 'Ethernet';if (conn.type === 'none') return 'No Network';// 处理蜂窝网络类型if (['cellular', 'mobile'].includes(conn.type || '')) {if (conn.effectiveType) {switch (conn.effectiveType) {case '5g': return '5G';case '4g': return '4G';case '3g': return '3G';case '2g': return '2G';default: return 'Cellular';}}// 按网络速度降级判断if (conn.downlink !== undefined) {if (conn.downlink >= 10) return '5G';if (conn.downlink >= 1) return '4G';if (conn.downlink >= 0.3) return '3G';return '2G';}return 'Cellular';}return 'Unknown';
};// 扩展 Navigator 类型以支持 userAgentData
interface Navigator {userAgentData?: {brands: Array<{brand: string;version: string;}>;};
}/*** 设置用户属性(覆盖式更新)* 自动获取部分基础属性,入参属性会覆盖同名自动属性* @param properties - 用户属性键值对(可选)*/
export const setAmplitudeUserProperties = async (properties?: UserProperties) => {if (!isInitialized || !instance) {console.error('Amplitude未初始化,请先调用initializeAmplitude');return;}const autoProps: Record<string, any> = {browser: navigator.userAgent.includes('Chrome') ? 'Chrome': navigator.userAgent.includes('Firefox') ? 'Firefox': navigator.userAgent.includes('Safari') ? 'Safari': navigator.userAgent.includes('Edge') ? 'Edge': 'Unknown',browser_version: navigator.appVersion,os: navigator.platform,screen_height: window.screen.height.toString(),screen_width: window.screen.width.toString(),network: getNetworkType(),// ip: ip,last_updated: formatDateTime(new Date()) // 最后更新时间};// 2. 处理用户传入的属性(覆盖自动属性)const processedProps: Record<string, any> = {...autoProps,...(properties || {})};// 3. 统一处理日期类型Object.entries(processedProps).forEach(([key, value]) => {processedProps[key] = value instanceof Date ? formatDateTime(value) // 使用统一的日期格式: value;});// 4. 执行覆盖式更新instance.setUserProperties(processedProps);
};/*** 更新用户属性(高级操作)* @param operations - 操作函数*/
export const updateAmplitudeUserProperties = (operations: (identify: Identify) => void
) => {if (!isInitialized || !instance) {console.error('Amplitude未初始化,请先调用initializeAmplitude');return;}// 从默认导出中创建Identify实例const identify = new amplitude.Identify();operations(identify);instance.identify(identify);
};/*** 跟踪收入数据* @param productId - 产品唯一标识* @param price - 产品价格* @param quantity - 购买数量* @param revenueType - 收入类型* @param properties - 附加属性*/
export const trackAmplitudeRevenue = (productId: string,price: number,quantity: number = 1,revenueType?: string,properties?: EventProperties
) => {if (!isInitialized || !instance) {console.error('Amplitude未初始化,请先调用initializeAmplitude');return;}// 从默认导出中创建Revenue实例const revenue = new amplitude.Revenue().setProductId(productId).setPrice(price).setQuantity(quantity);if (revenueType) revenue.setRevenueType(revenueType);if (properties) revenue.setEventProperties(properties);instance.logRevenueV2(revenue);
};/*** 控制跟踪状态* @param optOut - 是否禁用跟踪*/
export const setAmplitudeTrackingStatus = (optOut: boolean) => {if (!isInitialized || !instance) {console.error('Amplitude未初始化,请先调用initializeAmplitude');return;}instance.setOptOut(optOut);console.log(`Amplitude跟踪已${optOut ? '禁用' : '启用'}`);
};/*** 获取当前Amplitude实例* @returns Amplitude实例或null*/
export const getAmplitudeInstance = (): AmplitudeClient | null => {return instance;
};后续自定义事件(参数可完全自定义):
amplitudeEvent("kb_batch_read", {message: "知识库去研读",selected_count: selectedData.length,paper_id: selectedData,})项目Key
设置-> 组织 -> 项目

点击具体项目查看key

