feat(amplitude): add mobile implementation
This commit is contained in:
parent
19b4b92150
commit
59fc3642a6
2
Makefile
2
Makefile
|
@ -45,8 +45,6 @@ deploy-appbundle:
|
|||
$(OUTPUT_DIR)/analytics-ga.js \
|
||||
$(BUILD_DIR)/analytics-ga.min.js \
|
||||
$(BUILD_DIR)/analytics-ga.min.map \
|
||||
$(BUILD_DIR)/analytics-amplitude.min.js \
|
||||
$(BUILD_DIR)/analytics-amplitude.min.map \
|
||||
$(DEPLOY_DIR)
|
||||
|
||||
deploy-lib-jitsi-meet:
|
||||
|
|
|
@ -25,6 +25,7 @@ dependencies {
|
|||
implementation "com.android.support:appcompat-v7:${rootProject.ext.supportLibVersion}"
|
||||
|
||||
implementation 'org.webkit:android-jsc:+'
|
||||
implementation 'com.amplitude:android-sdk:2.14.1'
|
||||
implementation 'com.dropbox.core:dropbox-core-sdk:3.0.8'
|
||||
api 'com.facebook.react:react-native:+'
|
||||
|
||||
|
|
|
@ -53,6 +53,7 @@ class ReactInstanceManagerHolder {
|
|||
new PictureInPictureModule(reactContext),
|
||||
new ProximityModule(reactContext),
|
||||
new WiFiStatsModule(reactContext),
|
||||
new org.jitsi.meet.sdk.analytics.AmplitudeModule(reactContext),
|
||||
new org.jitsi.meet.sdk.dropbox.Dropbox(reactContext),
|
||||
new org.jitsi.meet.sdk.net.NAT64AddrInfoModule(reactContext)));
|
||||
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* Copyright @ 2019-present 8x8, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jitsi.meet.sdk.analytics;
|
||||
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
||||
import com.facebook.react.bridge.ReactMethod;
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
|
||||
import com.amplitude.api.Amplitude;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
/**
|
||||
* Implements the react-native module for the Amplitude integration.
|
||||
*/
|
||||
public class AmplitudeModule
|
||||
extends ReactContextBaseJavaModule {
|
||||
|
||||
public AmplitudeModule(ReactApplicationContext reactContext) {
|
||||
super(reactContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the Amplitude SDK.
|
||||
*
|
||||
* @param instanceName The name of the Amplitude instance. Should
|
||||
* be used only for multi-project logging.
|
||||
* @param apiKey The API_KEY of the Amplitude project.
|
||||
*/
|
||||
@ReactMethod
|
||||
public void init(String instanceName, String apiKey) {
|
||||
Amplitude.getInstance(instanceName).initialize(getCurrentActivity(), apiKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the user properties for an Amplitude instance.
|
||||
*
|
||||
* @param instanceName The name of the Amplitude instance.
|
||||
* @param userProps JSON string with user properties to be set.
|
||||
*/
|
||||
@ReactMethod
|
||||
public void setUserProperties(String instanceName, ReadableMap userProps) {
|
||||
if (userProps != null) {
|
||||
Amplitude.getInstance(instanceName).setUserProperties(
|
||||
new JSONObject(userProps.toHashMap()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Log an analytics event.
|
||||
*
|
||||
* @param instanceName The name of the Amplitude instance.
|
||||
* @param eventType The event type.
|
||||
* @param eventPropsString JSON string with the event properties.
|
||||
*/
|
||||
@ReactMethod
|
||||
public void logEvent(String instanceName, String eventType, String eventPropsString) {
|
||||
JSONObject eventProps = null;
|
||||
try {
|
||||
eventProps = new JSONObject(eventPropsString);
|
||||
Amplitude.getInstance(instanceName).logEvent(eventType, eventProps);
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Amplitude";
|
||||
}
|
||||
}
|
|
@ -35,6 +35,7 @@ target 'JitsiMeet' do
|
|||
pod 'Folly',
|
||||
:podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec'
|
||||
|
||||
pod 'Amplitude-iOS', '~> 4.0.4'
|
||||
pod 'ObjectiveDropboxOfficial'
|
||||
|
||||
pod 'react-native-background-timer',
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
PODS:
|
||||
- Amplitude-iOS (4.0.4)
|
||||
- boost-for-react-native (1.63.0)
|
||||
- BVLinearGradient (2.5.3):
|
||||
- React
|
||||
|
@ -154,6 +155,7 @@ PODS:
|
|||
- yoga (0.57.8.React)
|
||||
|
||||
DEPENDENCIES:
|
||||
- Amplitude-iOS (~> 4.0.4)
|
||||
- BVLinearGradient (from `../node_modules/react-native-linear-gradient`)
|
||||
- Crashlytics
|
||||
- DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`)
|
||||
|
@ -185,6 +187,7 @@ DEPENDENCIES:
|
|||
|
||||
SPEC REPOS:
|
||||
https://github.com/cocoapods/specs.git:
|
||||
- Amplitude-iOS
|
||||
- boost-for-react-native
|
||||
- Crashlytics
|
||||
- Fabric
|
||||
|
@ -235,6 +238,7 @@ EXTERNAL SOURCES:
|
|||
:path: "../node_modules/react-native/ReactCommon/yoga"
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
Amplitude-iOS: 2ad4d7270c99186236c1272a3a9425463b1ae1a7
|
||||
boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c
|
||||
BVLinearGradient: 0d985ec461359c82bc254f26d11008bdae50d17a
|
||||
Crashlytics: 07fb167b1694128c1c9a5a5cc319b0e9c3ca0933
|
||||
|
@ -268,6 +272,6 @@ SPEC CHECKSUMS:
|
|||
SDWebImage: c5594f1a19c48d526d321e548902b56b479cd508
|
||||
yoga: 74cdf036c30820443b25ade59916236b1e95ee93
|
||||
|
||||
PODFILE CHECKSUM: 7d1909450626f31f9ea2de80122a66a50af2e1ea
|
||||
PODFILE CHECKSUM: b300161e95d65c24b91368803afb8873f4b873cc
|
||||
|
||||
COCOAPODS: 1.6.0
|
||||
COCOAPODS: 1.6.1
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
75635B0B20751D6D00F29C9F /* left.wav in Resources */ = {isa = PBXBuildFile; fileRef = 75635B0920751D6D00F29C9F /* left.wav */; };
|
||||
87FE6F3321E52437004A5DC7 /* incomingMessage.wav in Resources */ = {isa = PBXBuildFile; fileRef = 87FE6F3221E52437004A5DC7 /* incomingMessage.wav */; };
|
||||
A4414AE020B37F1A003546E6 /* rejected.wav in Resources */ = {isa = PBXBuildFile; fileRef = A4414ADF20B37F1A003546E6 /* rejected.wav */; };
|
||||
A480429C21EE335600289B73 /* AmplitudeModule.m in Sources */ = {isa = PBXBuildFile; fileRef = A480429B21EE335600289B73 /* AmplitudeModule.m */; };
|
||||
A4A934E9212F3ADB001E9388 /* Dropbox.m in Sources */ = {isa = PBXBuildFile; fileRef = A4A934E8212F3ADB001E9388 /* Dropbox.m */; };
|
||||
C6245F5D2053091D0040BE68 /* image-resize@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = C6245F5B2053091D0040BE68 /* image-resize@2x.png */; };
|
||||
C6245F5E2053091D0040BE68 /* image-resize@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = C6245F5C2053091D0040BE68 /* image-resize@3x.png */; };
|
||||
|
@ -80,6 +81,7 @@
|
|||
98E09B5C73D9036B4ED252FC /* Pods-JitsiMeet.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-JitsiMeet.debug.xcconfig"; path = "../Pods/Target Support Files/Pods-JitsiMeet/Pods-JitsiMeet.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
9C77CA3CC919B081F1A52982 /* Pods-JitsiMeet.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-JitsiMeet.release.xcconfig"; path = "../Pods/Target Support Files/Pods-JitsiMeet/Pods-JitsiMeet.release.xcconfig"; sourceTree = "<group>"; };
|
||||
A4414ADF20B37F1A003546E6 /* rejected.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; name = rejected.wav; path = ../../sounds/rejected.wav; sourceTree = "<group>"; };
|
||||
A480429B21EE335600289B73 /* AmplitudeModule.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AmplitudeModule.m; path = src/analytics/AmplitudeModule.m; sourceTree = SOURCE_ROOT; };
|
||||
A4A934E8212F3ADB001E9388 /* Dropbox.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Dropbox.m; sourceTree = "<group>"; };
|
||||
A4A934EB21349A06001E9388 /* Dropbox.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Dropbox.h; sourceTree = "<group>"; };
|
||||
C6245F5B2053091D0040BE68 /* image-resize@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "image-resize@2x.png"; path = "src/picture-in-picture/image-resize@2x.png"; sourceTree = "<group>"; };
|
||||
|
@ -148,6 +150,7 @@
|
|||
0BD906E71EC0C00300C8C18E /* src */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A480429821ECE2D800289B73 /* analytics */,
|
||||
0BB9AD7C1F60356D001C08DB /* AppInfo.m */,
|
||||
0BCA495C1EC4B6C600B793EE /* AudioMode.m */,
|
||||
C69EFA02209A0EFD0027712B /* callkit */,
|
||||
|
@ -183,6 +186,15 @@
|
|||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A480429821ECE2D800289B73 /* analytics */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A480429B21EE335600289B73 /* AmplitudeModule.m */,
|
||||
);
|
||||
name = analytics;
|
||||
path = "New Group";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A4A934E7212F3AB8001E9388 /* dropbox */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -374,6 +386,10 @@
|
|||
);
|
||||
inputPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-JitsiMeet/Pods-JitsiMeet-resources.sh",
|
||||
"${PODS_ROOT}/Amplitude-iOS/Amplitude/api.amplitude.com.der",
|
||||
"${PODS_ROOT}/Amplitude-iOS/Amplitude/ComodoCaLimitedRsaCertificationAuthority.der",
|
||||
"${PODS_ROOT}/Amplitude-iOS/Amplitude/ComodoRsaCA.der",
|
||||
"${PODS_ROOT}/Amplitude-iOS/Amplitude/ComodoRsaDomainValidationCA.der",
|
||||
"${PODS_ROOT}/GoogleSignIn/Resources/GoogleSignIn.bundle",
|
||||
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/AntDesign.ttf",
|
||||
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Entypo.ttf",
|
||||
|
@ -393,6 +409,10 @@
|
|||
);
|
||||
name = "[CP] Copy Pods Resources";
|
||||
outputPaths = (
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/api.amplitude.com.der",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ComodoCaLimitedRsaCertificationAuthority.der",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ComodoRsaCA.der",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ComodoRsaDomainValidationCA.der",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/GoogleSignIn.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AntDesign.ttf",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Entypo.ttf",
|
||||
|
@ -433,6 +453,7 @@
|
|||
0BCA495F1EC4B6C600B793EE /* AudioMode.m in Sources */,
|
||||
0B44A0191F902126009D1D64 /* MPVolumeViewManager.m in Sources */,
|
||||
0BCA49611EC4B6C600B793EE /* Proximity.m in Sources */,
|
||||
A480429C21EE335600289B73 /* AmplitudeModule.m in Sources */,
|
||||
C69EFA0C209A0F660027712B /* JMCallKitEmitter.swift in Sources */,
|
||||
C6A34261204EF76800E062DD /* DragGestureController.swift in Sources */,
|
||||
A4A934E9212F3ADB001E9388 /* Dropbox.m in Sources */,
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright @ 2018-present 8x8, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import <React/RCTBridgeModule.h>
|
||||
#import "Amplitude.h"
|
||||
|
||||
@interface AmplitudeModule : NSObject<RCTBridgeModule>
|
||||
|
||||
@end
|
||||
|
||||
@implementation AmplitudeModule
|
||||
|
||||
RCT_EXPORT_MODULE(Amplitude)
|
||||
|
||||
+ (BOOL)requiresMainQueueSetup {
|
||||
return NO;
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(init:(NSString*)instanceName API_KEY:(NSString*)apiKey) {
|
||||
[[Amplitude instanceWithName:instanceName] initializeApiKey:apiKey];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(setUserProperties:(NSString*)instanceName userPropsString:(NSDictionary*)userProps) {
|
||||
if (userProps != nil) {
|
||||
[[Amplitude instanceWithName:instanceName] setUserProperties:userProps];
|
||||
}
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(logEvent:(NSString*)instanceName eventType:(NSString*)eventType eventPropsString:(NSString*)eventPropsString) {
|
||||
NSError *error;
|
||||
NSData *eventPropsData = [eventPropsString dataUsingEncoding:NSUTF8StringEncoding];
|
||||
NSDictionary *eventProperties = [NSJSONSerialization JSONObjectWithData:eventPropsData
|
||||
options:NSJSONReadingMutableContainers
|
||||
error:&error];
|
||||
if (eventProperties == nil) {
|
||||
NSLog(@"[Amplitude handler] Error parsing event properties: %@", error);
|
||||
} else {
|
||||
[[Amplitude instanceWithName:instanceName] logEvent:eventType withEventProperties:eventProperties];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
|
@ -6,6 +6,8 @@ import JitsiMeetJS, {
|
|||
} from '../base/lib-jitsi-meet';
|
||||
import { getJitsiMeetGlobalNS, loadScript } from '../base/util';
|
||||
|
||||
import { AmplitudeHandler } from './handlers';
|
||||
|
||||
const logger = require('jitsi-meet-logger').getLogger(__filename);
|
||||
|
||||
/**
|
||||
|
@ -23,6 +25,16 @@ export function sendAnalytics(event: Object) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the analytics adapter to its initial state - removes handlers, cache,
|
||||
* disabled state, etc.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
export function resetAnalytics() {
|
||||
analytics.reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the analytics scripts and inits JitsiMeetJS.analytics by setting
|
||||
* permanent properties and setting the handlers from the loaded scripts.
|
||||
|
@ -43,6 +55,9 @@ export function initAnalytics({ getState }: { getState: Function }) {
|
|||
|
||||
const state = getState();
|
||||
const config = state['features/base/config'];
|
||||
const { locationURL } = state['features/base/connection'];
|
||||
const host = locationURL ? locationURL.host : '';
|
||||
|
||||
const {
|
||||
analytics: analyticsConfig = {},
|
||||
deploymentInfo
|
||||
|
@ -58,6 +73,7 @@ export function initAnalytics({ getState }: { getState: Function }) {
|
|||
envType: (deploymentInfo && deploymentInfo.envType) || 'dev',
|
||||
googleAnalyticsTrackingId,
|
||||
group,
|
||||
host,
|
||||
product: deploymentInfo && deploymentInfo.product,
|
||||
subproduct: deploymentInfo && deploymentInfo.environment,
|
||||
user: user && user.id,
|
||||
|
@ -109,7 +125,7 @@ export function initAnalytics({ getState }: { getState: Function }) {
|
|||
* successfully loaded and rejects if there are no handlers loaded or the
|
||||
* analytics is disabled.
|
||||
*/
|
||||
function _loadHandlers(scriptURLs, handlerConstructorOptions) {
|
||||
function _loadHandlers(scriptURLs = [], handlerConstructorOptions) {
|
||||
const promises = [];
|
||||
|
||||
for (const url of scriptURLs) {
|
||||
|
@ -139,12 +155,12 @@ function _loadHandlers(scriptURLs, handlerConstructorOptions) {
|
|||
// check the old location to provide legacy support
|
||||
const analyticsHandlers = [
|
||||
...getJitsiMeetGlobalNS().analyticsHandlers,
|
||||
...window.analyticsHandlers
|
||||
];
|
||||
...window.analyticsHandlers,
|
||||
|
||||
if (analyticsHandlers.length === 0) {
|
||||
throw new Error('No analytics handlers available');
|
||||
}
|
||||
// NOTE: when we add second handler it will be good to put all
|
||||
// build-in handlers in an array and destruct it here.
|
||||
AmplitudeHandler
|
||||
];
|
||||
|
||||
const handlers = [];
|
||||
|
||||
|
|
|
@ -1,15 +1,12 @@
|
|||
import amplitude from 'amplitude-js';
|
||||
|
||||
import { getJitsiMeetGlobalNS } from '../../base/util';
|
||||
|
||||
import AbstractHandler from './AbstractHandler';
|
||||
import { amplitude } from './amplitude';
|
||||
|
||||
const logger = require('jitsi-meet-logger').getLogger(__filename);
|
||||
|
||||
/**
|
||||
* Analytics handler for Amplitude.
|
||||
*/
|
||||
class AmplitudeHandler extends AbstractHandler {
|
||||
export default class AmplitudeHandler extends AbstractHandler {
|
||||
/**
|
||||
* Creates new instance of the Amplitude analytics handler.
|
||||
*
|
||||
|
@ -20,18 +17,22 @@ class AmplitudeHandler extends AbstractHandler {
|
|||
constructor(options) {
|
||||
super();
|
||||
|
||||
const { amplitudeAPPKey } = options;
|
||||
const { amplitudeAPPKey, host } = options;
|
||||
|
||||
if (!amplitudeAPPKey) {
|
||||
logger.warn(
|
||||
'Failed to initialize Amplitude handler, no tracking ID');
|
||||
'Failed to initialize Amplitude handler, no APP key');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this._enabled = true;
|
||||
|
||||
amplitude.getInstance().init(amplitudeAPPKey);
|
||||
this._amplitudeOptions = {
|
||||
host
|
||||
};
|
||||
|
||||
amplitude.getInstance(this._amplitudeOptions).init(amplitudeAPPKey);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -42,7 +43,8 @@ class AmplitudeHandler extends AbstractHandler {
|
|||
*/
|
||||
setUserProperties(userProps) {
|
||||
if (this._enabled) {
|
||||
amplitude.getInstance().setUserProperties(userProps);
|
||||
amplitude.getInstance(this._amplitudeOptions)
|
||||
.setUserProperties(userProps);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -59,13 +61,8 @@ class AmplitudeHandler extends AbstractHandler {
|
|||
return;
|
||||
}
|
||||
|
||||
amplitude.getInstance().logEvent(
|
||||
amplitude.getInstance(this._amplitudeOptions).logEvent(
|
||||
this._extractName(event),
|
||||
event);
|
||||
}
|
||||
}
|
||||
|
||||
const globalNS = getJitsiMeetGlobalNS();
|
||||
|
||||
globalNS.analyticsHandlers = globalNS.analyticsHandlers || [];
|
||||
globalNS.analyticsHandlers.push(AmplitudeHandler);
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
import { NativeModules } from 'react-native';
|
||||
|
||||
const { Amplitude: AmplitudeNative } = NativeModules;
|
||||
|
||||
/**
|
||||
* Wrapper for the Amplitude native module.
|
||||
*/
|
||||
class Amplitude {
|
||||
/**
|
||||
* Create new Amplitude instance.
|
||||
*
|
||||
* @param {string} instanceName - The name of the Amplitude instance. Should
|
||||
* be used only for multi-project logging.
|
||||
*/
|
||||
constructor(instanceName) {
|
||||
this._instanceName = instanceName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the Amplitude SDK.
|
||||
*
|
||||
* @param {string} apiKey - The API_KEY of the Amplitude project.
|
||||
* @returns {void}
|
||||
*/
|
||||
init(apiKey) {
|
||||
AmplitudeNative.init(this._instanceName, apiKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets user properties for the current user.
|
||||
*
|
||||
* @param {Object} userProperties - The user properties to be set.
|
||||
* @returns {void}
|
||||
*/
|
||||
setUserProperties(userProperties) {
|
||||
AmplitudeNative.setUserProperties(this._instanceName, userProperties);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log an event with eventType and eventProperties.
|
||||
*
|
||||
* @param {string} eventType - The type of the event.
|
||||
* @param {Object} eventProperties - The properties of the event.
|
||||
* @returns {void}
|
||||
*/
|
||||
logEvent(eventType, eventProperties) {
|
||||
// The event properties are converted to JSON string because of known
|
||||
// performance issue when passing objects trough the RN bridge too
|
||||
// often (a few times a second).
|
||||
AmplitudeNative.logEvent(
|
||||
this._instanceName, eventType, JSON.stringify(eventProperties));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Cache of <tt>Amplitude</tt> instances by instanceName.
|
||||
*/
|
||||
const instances = {};
|
||||
|
||||
/**
|
||||
* The default (with instanceName - undefined) <tt>Amplitude</tt> instance.
|
||||
*/
|
||||
let defaultInstance;
|
||||
|
||||
export default {
|
||||
/**
|
||||
* Returns a <tt>Amplitude</tt> instance.
|
||||
*
|
||||
* @param {Object} options - Optional parameters.
|
||||
* @param {string} options.host - The host property from the current URL.
|
||||
* @param {string|undefined} options.instanceName - The name of the
|
||||
* amplitude instance. Should be used only for multi-project logging.
|
||||
* @returns {Amplitude}
|
||||
*/
|
||||
getInstance(options = {}) {
|
||||
let instance;
|
||||
|
||||
const { host = '', instanceName = '' } = options;
|
||||
|
||||
let internalInstanceName = host;
|
||||
|
||||
if (instanceName !== '') {
|
||||
internalInstanceName += `-${instanceName}`;
|
||||
}
|
||||
|
||||
if (internalInstanceName === '') {
|
||||
instance = defaultInstance = defaultInstance || new Amplitude();
|
||||
} else {
|
||||
instance = instances[internalInstanceName]
|
||||
= instances[internalInstanceName]
|
||||
|| new Amplitude(internalInstanceName);
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
};
|
|
@ -0,0 +1,7 @@
|
|||
import amplitude from 'amplitude-js';
|
||||
|
||||
export default {
|
||||
getInstance(options = {}) {
|
||||
return amplitude.getInstance(options.instanceName);
|
||||
}
|
||||
};
|
|
@ -0,0 +1 @@
|
|||
export { default as amplitude } from './Amplitude';
|
|
@ -0,0 +1 @@
|
|||
export { default as AmplitudeHandler } from './AmplitudeHandler';
|
|
@ -1,7 +1,8 @@
|
|||
import { SET_ROOM } from '../base/conference';
|
||||
import { SET_CONFIG } from '../base/config';
|
||||
import { MiddlewareRegistry } from '../base/redux';
|
||||
|
||||
import { initAnalytics } from './functions';
|
||||
import { initAnalytics, resetAnalytics } from './functions';
|
||||
|
||||
/**
|
||||
* Middleware which intercepts config actions to handle evaluating analytics
|
||||
|
@ -12,6 +13,16 @@ import { initAnalytics } from './functions';
|
|||
*/
|
||||
MiddlewareRegistry.register(store => next => action => {
|
||||
switch (action.type) {
|
||||
case SET_CONFIG: {
|
||||
if (navigator.product === 'ReactNative') {
|
||||
// Reseting the analytics is currently not needed for web because
|
||||
// the user will be redirected to another page and new instance of
|
||||
// Analytics will be created and initialized.
|
||||
resetAnalytics();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case SET_ROOM: {
|
||||
const result = next(action);
|
||||
|
||||
|
|
|
@ -43,16 +43,7 @@ export function createLocalTrack(type: string, deviceId: string) {
|
|||
* otherwise.
|
||||
*/
|
||||
export function isAnalyticsEnabled(stateful: Function | Object) {
|
||||
const {
|
||||
analytics = {},
|
||||
disableThirdPartyRequests
|
||||
} = toState(stateful)['features/base/config'];
|
||||
const { scriptURLs } = analytics;
|
||||
|
||||
return (
|
||||
!disableThirdPartyRequests
|
||||
&& Array.isArray(scriptURLs)
|
||||
&& Boolean(scriptURLs.length));
|
||||
return !toState(stateful)['features/base/config'].disableThirdPartyRequests;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -135,9 +135,7 @@ module.exports = [
|
|||
'./react/features/local-recording/'
|
||||
+ 'recording/flac/flacEncodeWorker.js',
|
||||
'analytics-ga':
|
||||
'./react/features/analytics/handlers/GoogleAnalyticsHandler.js',
|
||||
'analytics-amplitude':
|
||||
'./react/features/analytics/handlers/AmplitudeHandler.js'
|
||||
'./react/features/analytics/handlers/GoogleAnalyticsHandler.js'
|
||||
}
|
||||
}),
|
||||
|
||||
|
|
Loading…
Reference in New Issue