mParticle Capacitor Plugin
npm install npm i @hathway/mparticle-capacitor
npx cap sync
Use mParticleConfig
to create a configuration object used to initialize mParticle.
app.component.ts
in ngOnInit()
import {MParticleCapacitor} from 'mparticle-capacitor';
...
let mParticleKey = "YOUR KEY"
MParticleCapacitor.mParticleConfig({
isDevelopmentMode: true,
planID: "PLAN NAME",
planVer: 2,
logLevel: "verbose", // || "warning" || "none"
}).then((config:any) => {
if (!this.platform.is('hybrid')) {
// add web kits here i.e.:
// mParticleBraze.register(config);
}
MParticleCapacitor.mParticleInit({key: mParticleKey, mParticleConfig: config})
.catch((e:any) => {}); // initialize mparticle web, catch when ios/android return unimplemented.
}).catch((e:any) => {});
/* or */
if (!this.platform.is('hybrid')) { initMP(); }
async initMP() {
let mParticleKey = "YOUR KEY"
let mpConfig = await MParticleCapacitor.mParticleConfig({
isDevelopmentMode: true,
planID: "PLAN NAME",
planVer: 2,
logLevel: "verbose", // || "warning" || "none"
});
// add web kits here i.e.:
// mParticleBraze.register(mpConfig);
MParticleCapacitor.mParticleInit({key: mParticleKey, mParticleConfig: mpConfig});
}
Initilize mParticle in the app directly instead of the plugin, Appboy/Braze needs the permissions mParticle will pass to it through this.
MainActivity.java
in onCreate()
import com.mparticle.MParticle;
import com.mparticle.MParticleOptions;
...
public class MainActivity extends BridgeActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
MParticleOptions options = MParticleOptions.builder(this)
.credentials( "YOUR KEY HERE", "MATCHING SECRET" )
.environment(MParticle.Environment.Development) // or MParticle.Environment.Production
.dataplan("master_data_plan", 2)
.logLevel(MParticle.LogLevel.DEBUG) // to see debug logging in Android Studio
.androidIdEnabled(true) // required for SDK 5.35+
.build();
MParticle.start(options);
}
}
can't find "com.mparticle...."? add android:exported="true"
to AndroidMnifest.xml
under <activity>
>
Initilize mParticle in the app directly instead of the plugin, Appboy/Braze needs the permissions mParticle will pass to it through this.
AppDelegate.swift
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
let options = MParticleOptions(key: "YOUR KEY HERE", secret: "MATCHING SECRET")
options.environment = MPEnvironment.development; // or MPEnvironment.production
options.dataPlanId = "master_data_plan"
options.logLevel = MPILogLevel.verbose // to see debug logging in XCode
MParticle.sharedInstance().start(with: options)
return true
}
All available kits can be found here: https://github.com/mparticle-integrations
MParticle provides a "black-box" solution to data sharing between other api. Kits do not need to be added to the plugin, they can be added directly to your app's Podfile (iOS)
or build.gradle (Android)
or into your app.component.ts (web)
.
Web kits are added before the web initialization in the component. If there is an error with the inport:
Error: export 'MParticleBraze' (imported as 'MParticleBraze') was not found...
import using require
:
const mParticleBraze = require('@mparticle/web-braze-kit');
mParticle will handle the integration internally as long as things are hooked up in the dashboard.
There are some custom settings and inclusions that need to be included in your project for mParticle to route data to Braze properly.
Android will complain about not finding a package unless you include this repo in your build.gradle
:
repositories {
maven { url "https://appboy.github.io/appboy-android-sdk/sdk" }
...
}
dependencies {
implementation 'com.mparticle:android-appboy-kit:5+'
}
Full documentation here: https://github.com/mparticle-integrations/mparticle-android-integration-appboy
Add the kit to your app's Podfile:
pod 'mParticle-Appboy', '~> 8'
Add Firebase to your build.gradle
compile 'com.google.firebase:firebase-core:<YOUR_PLAY_SERVICES_VERSION>'
compile 'com.google.firebase:firebase-messaging:<YOUR_PLAY_SERVICES_VERSION>'
Add mParticle's InstanceService to AndroidManifest.xml
<service android:name="com.mparticle.messaging.InstanceIdService" />
<receiver
android:name="com.mparticle.MPReceiver"
android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<!-- Use your package name as the category -->
<category android:name="YOURPACKAGENAME" />
</intent-filter>
</receiver>
<!-- This is the service that does the heavy lifting in parsing, showing, and tracking FCM/GCM notifications. -->
<service android:name="com.mparticle.MPService" />
Add this to your MainActivity.java
after your mParticle init
MParticle.getInstance().Messaging().enablePushNotifications( "YOUR SENDER ID" );
Full mParticle Documentation Here: https://docs.mparticle.com/developers/sdk/android/push-notifications/
Add BrazeFirebaseMessagingService
to your AndroidManifest.xml
<service android:name="com.braze.push.BrazeFirebaseMessagingService" android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
Create a braze.xml
file in android/app/src/main/res/values
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="com_braze_default_notification_accent_color">@android:color/black</color> <!--Sets Icon Background Default-->
<drawable name="com_braze_push_small_notification_icon">@drawable/ic_star_face_larger_notification</drawable> <!--Sets Default Large Icon-->
<drawable name="com_braze_push_large_notification_icon">@drawable/ic_star_vector</drawable> <!--Sets Default Small Icon-->
<bool name="com_braze_handle_push_deep_links_automatically">true</bool> <!--Required to allow notification to open app-->
</resources>
Full Documentation Here: https://www.braze.com/docs/developer_guide/platform_integration_guides/android/push_notifications/android/integration/standard_integration/#custom-handling-for-push-receipts-opens-dismissals-and-key-value-pairs
mParticle will handle the integration internaly. There may be issues depending on other packages in your app. Full mParticle documentation here: https://docs.mparticle.com/developers/sdk/ios/push-notifications/
iOS does not pass push tokens automatically, for your hybrid app I recommend using: https://capacitorjs.com/docs/apis/push-notifications to request and enable push notifictaions for your users
Look for functions that override or proxy the AppDelegate functions specifically didRegisterForRemoteNotificationsWithDeviceToken
. Firebase Gets in the way of Braze And mParticle interactions
ref: https://firebase.google.com/docs/cloud-messaging/ios/client The FCM SDK performs method swizzling in two key areas: mapping your APNs token to the FCM registration token and capturing analytics data during downstream message callback handling. Developers who prefer not to use swizzling can disable it by adding the flag FirebaseAppDelegateProxyEnabled in the app’s Info.plist file and setting it to NO (boolean value). Relevant areas of the guides provide code examples, both with and without method swizzling enabled.
solution is in your Info.plist
:
(via. https://firebase.google.com/docs/cloud-messaging/ios/client)
AppsFlyer works as expected out of the box. Most of the settings will be handled between the dashboards.
Add the AppsFlyer kit to your app's build.gradle
:
dependencies {
implementation 'com.mparticle:android-appsflyer-kit:5+'
}
Full documentation here: https://github.com/mparticle-integrations/mparticle-android-integration-appsflyer
Add the kit to your app's Podfile:
pod 'mParticle-AppsFlyer', '~> 8'
Full documentation here: https://github.com/mparticle-integrations/mparticle-apple-integration-appsflyer
The AppsFlyer capacitor plugin can work in parallell with the kit to process the deeplinks
npm install appsflyer-capacitor-plugin
npx cap sync
Note that we add the listener before the init.
AppsFlyer.addListener(AFConstants.UDL_CALLBACK, (res) => {
console.log('URL APPSFLYER UDL_CALLBACK ~~>' + JSON.stringify(res));
if (res.status === 'FOUND') {
// do the deeplink process
} else if (res.status === 'ERROR') {
console.log('deep link error');
} else {
console.log('deep link not found');
}
});
AppsFlyer.initSDK({
appID: '{APPID}', // replace with your app ID.
devKey: '{DEVKEY}', // replace with your dev key.
isDebug: true,
waitForATTUserAuthorization: 10, // for iOS 14 and higher
registerOnDeepLink: true,
registerConversionListener: true,
}).then().catch(e =>console.log("AppsFlyer Error Catch",e));
It is also recommended to encapulate the above code in if (platform.is('hybrid')) {
or something similar as this listener will throw an 'unimplemented' error when in a web environment. AppsFlyer documentation also recommends to start in this.platform.ready().then(() => {
.
Full documentation here: https://github.com/AppsFlyerSDK/appsflyer-capacitor-plugin
echo(...)
mParticleConfig(...)
mParticleInit(...)
loginMParticleUser(...)
logoutMParticleUser(...)
getAllUserAttributes(...)
logMParticleEvent(...)
logMParticlePageView(...)
setUserAttribute(...)
setUserAttributeList(...)
removeUserAttribute(...)
updateMParticleCart(...)
addMParticleProduct(...)
removeMParticleProduct(...)
submitPurchaseEvent(...)
registerMParticleUser(...)
- Interfaces
- Type Aliases
echo(options: { value: string; }) => Promise<{ value: string; }>
Param | Type |
---|---|
options |
{ value: string; } |
Returns: Promise<{ value: string; }>
mParticleConfig(call: MParticleConfigArguments) => Promise<MPConfigType>
Param | Type |
---|---|
call |
MParticleConfigArguments |
Returns: Promise<MPConfigType>
mParticleInit(call: { key: string; mParticleConfig: any; }) => Promise<IdentityResult>
Param | Type |
---|---|
call |
{ key: string; mParticleConfig: any; } |
Returns: Promise<IdentityResult>
loginMParticleUser(call: { email: string; customerId?: string; }) => Promise<{ value: string; }>
Param | Type |
---|---|
call |
{ email: string; customerId?: string; } |
Returns: Promise<{ value: string; }>
logoutMParticleUser(call?: any) => Promise<mParticle.IdentityResult>
Param | Type |
---|---|
call |
any |
Returns: Promise<IdentityResult>
getAllUserAttributes(call?: any) => AllUserAttributes
Param | Type |
---|---|
call |
any |
Returns: AllUserAttributes
logMParticleEvent(call: { eventName: string; eventType: any; eventProperties: any; }) => void
Param | Type |
---|---|
call |
{ eventName: string; eventType: any; eventProperties: any; } |
logMParticlePageView(call: { pageName: string; pageLink: any; overrides?: any; }) => void
Param | Type |
---|---|
call |
{ pageName: string; pageLink: any; overrides?: any; } |
setUserAttribute(call: { attributeName: string; attributeValue: string; }) => void
Param | Type |
---|---|
call |
{ attributeName: string; attributeValue: string; } |
setUserAttributeList(call: { attributeName: string; attributeValues: any; }) => void
Param | Type |
---|---|
call |
{ attributeName: string; attributeValues: any; } |
removeUserAttribute(call: { attributeName: string; }) => void
Param | Type |
---|---|
call |
{ attributeName: string; } |
updateMParticleCart(call: { productData: any; customAttributes: any; eventType: any; }) => void
Param | Type |
---|---|
call |
{ productData: any; customAttributes: any; eventType: any; } |
addMParticleProduct(call: { productData: any; customAttributes: any; }) => void
Param | Type |
---|---|
call |
{ productData: any; customAttributes: any; } |
removeMParticleProduct(call: { productData: any; customAttributes: any; }) => void
Param | Type |
---|---|
call |
{ productData: any; customAttributes: any; } |
submitPurchaseEvent(call: { productData: any; customAttributes: any; transactionAttributes: any; }) => void
Param | Type |
---|---|
call |
{ productData: any; customAttributes: any; transactionAttributes: any; } |
registerMParticleUser(call: { email: string; customerId?: string; userAttributes: any; }) => Promise<any>
Param | Type |
---|---|
call |
{ email: string; customerId?: string; userAttributes: any; } |
Returns: Promise<any>
Prop | Type |
---|---|
httpCode |
any |
body |
IdentityResultBody |
Method | Signature |
---|---|
getPreviousUser | () => User |
getUser | () => User |
Prop | Type |
---|---|
getUserIdentities |
() => IdentityApiData |
getMPID |
() => string |
setUserTag |
(tag: string) => void |
removeUserTag |
(tag: string) => void |
setUserAttribute |
(key: string, value: string) => void |
setUserAttributes |
(attributeObject: Record<string, unknown>) => void |
removeUserAttribute |
(key: string) => void |
setUserAttributeList |
(key: string, value: UserAttributesValue[]) => void |
removeAllUserAttributes |
() => void |
getUserAttributesLists |
() => Record<string, UserAttributesValue[]> |
getAllUserAttributes |
() => AllUserAttributes |
getCart |
() => Cart |
getConsentState |
() => ConsentState |
setConsentState |
(ConsentState: ConsentState) => void |
isLoggedIn |
() => boolean |
getLastSeenTime |
() => number |
getFirstSeenTime |
() => number |
Prop | Type |
---|---|
userIdentities |
UserIdentities |
Prop | Type |
---|---|
customerid |
string |
email |
string |
other |
string |
other2 |
string |
other3 |
string |
other4 |
string |
other5 |
string |
other6 |
string |
other7 |
string |
other8 |
string |
other9 |
string |
other10 |
string |
mobile_number |
string |
phone_number_2 |
string |
phone_number_3 |
string |
facebook |
string |
facebookcustomaudienceid |
string |
google |
string |
twitter |
string |
microsoft |
string |
yahoo |
string |
Prop | Type |
---|---|
add |
(product: Product, logEventBoolean?: boolean) => void |
remove |
(product: Product, logEventBoolean?: boolean) => void |
clear |
() => void |
Prop | Type |
---|---|
id |
string |
name |
string |
brand |
string |
category |
string |
variant |
string |
position |
number |
price |
number |
quantity |
number |
coupon_code |
string |
added_to_cart_time_ms |
number |
total_product_amount |
number |
custom_attributes |
{ [key: string]: string; } |
Prop | Type |
---|---|
gdpr |
{ [key: string]: GDPRConsentState; } |
ccpa |
{ data_sale_opt_out: CCPAConsentState; } |
Prop | Type |
---|---|
purpose |
string |
document |
string |
consented |
boolean |
timestamp_unixtime_ms |
number |
location |
string |
hardware_id |
string |
Prop | Type |
---|---|
Consented |
boolean |
Timestamp |
number |
ConsentDocument |
string |
Location |
string |
HardwareId |
string |
Prop | Type |
---|---|
context |
string | null |
is_ephemeral |
boolean |
is_logged_in |
boolean |
matched_identities |
Record<string, unknown> |
Prop | Type |
---|---|
isDevelopmentMode |
boolean |
planID |
string |
planVer |
number |
planVersionRequired |
boolean |
logLevel |
string |
identifyRequest |
any |
identityCallback |
((i: IdentityResult) => void) |
{ isDevelopmentMode?: boolean, dataPlan?: { planId?: string, planVersion?: number }, identifyRequest?: any, logLevel?: string, identityCallback?: (i: IdentityResult) => void, }
{ customerid?: string; email?: string; other?: string; other2?: string; other3?: string; other4?: string; other5?: string; other6?: string; other7?: string; other8?: string; other9?: string; other10?: string; mobile_number?: string; phone_number_2?: string; phone_number_3?: string; facebook?: string; facebookcustomaudienceid?: string; google?: string; twitter?: string; microsoft?: string; yahoo?: string; }
string
Construct a type with a set of properties K of type T
{
[P in K]: T;
}
string | number | boolean | null
Record<string, UserAttributesValue | UserAttributesValue[]>
{ name: string; sku: string; price: number; quantity?: number; variant?: string; category?: string; brand?: string; position?: number; coupon?: string; attributes?: Record<string, unknown>; }
{ /** * * @deprecated Cart persistence in mParticle has been deprecated. Please use mParticle.eCommerce.logProductAction(mParticle.ProductActionType.AddToCart, [products]) / add: (product: Product, logEventBoolean?: boolean) => void; /* * * @deprecated Cart persistence in mParticle has been deprecated. Please use mParticle.eCommerce.logProductAction(mParticle.ProductActionType.RemoveFromCart, [products]) / remove: (product: Product, logEventBoolean?: boolean) => void; /* * * @deprecated Cart persistence in mParticle has been deprecated. */ clear: () => void; }
{ [key: string]: PrivacyConsentState; }
{ Consented: boolean; Timestamp: number; ConsentDocument: string; Location: string; HardwareId: string; }
Omit<GDPRConsentState, 'purpose'>
Construct a type with the properties of T except for those in type K.
From T, pick a set of properties whose keys are in the union K
{
[P in K]: T[P];
}
Exclude from T those types that are assignable to U
T extends U ? never : T
{ setGDPRConsentState: (gdprConsentState: GDPRConsentState) => ConsentState; setCCPAConsentState: (ccpaConsentState: CCPAConsentState) => ConsentState; addGDPRConsentState: ( purpose: string, gdprConsent: PrivacyConsentState, ) => ConsentState; getGDPRConsentState: () => GDPRConsentState; getCCPAConsentState: () => CCPAConsentState; removeGDPRConsentState: (purpose: string) => ConsentState; removeCCPAConsentState: () => ConsentState; }
{ getUserIdentities: () => UserIdentities; getMPID: () => MPID; setUserTag: (tag: string) => void; removeUserTag: (tag: string) => void; setUserAttribute: (key: string, value: string) => void; setUserAttributes: (attributeObject: Record<string, unknown>) => void; removeUserAttribute: (key: string) => void; setUserAttributeList: (key: string, value: UserAttributesValue[]) => void; removeAllUserAttributes: () => void; getUserAttributesLists: () => Record<string, UserAttributesValue[]>; getAllUserAttributes: () => AllUserAttributes; /** * * @deprecated Cart persistence in mParticle has been deprecated */ getCart: () => Cart; getConsentState: () => ConsentState; setConsentState: (ConsentState: ConsentState) => void; isLoggedIn: () => boolean; getLastSeenTime: () => number; getFirstSeenTime: () => number; }
{ httpCode: any; getPreviousUser(): User; getUser(): User; body: IdentityResultBody; }