# Mixpanel

Target cohorts using Airship tags and feed Airship RTDS events into Mixpanel.

The Mixpanel integration supports two major functions:

* **Feed [Real-Time Data Streaming](https://www.airship.com/docs/reference/glossary/#rtds) events into Mixpanel.** Adding Airship events to Mixpanel provides another behavioral dimension to analyze: audience engagement.

* **Export Mixpanel cohorts to Airship as tags.** You can export cohorts once or set up *dynamic sync*, which updates the `mixpanel` tag group every 15 minutes. You can then target Mixpanel tags when creating messages:
   * **Segmentation:** Create a [segment](https://www.airship.com/docs/reference/glossary/#segment) using a combination of Airship tags and Mixpanel cohorts. Use these segments to send targeted [In-App](https://www.airship.com/docs/reference/glossary/#in_app_message) or [Message Center](https://www.airship.com/docs/reference/glossary/#message_center) messages.

   * **Automation:** If you set the Mixpanel cohort to be dynamic, you can also set up [Automations and Sequences](https://www.airship.com/docs/guides/messaging/messages/sequences/about/) based on the addition or removal of a cohort tag. See [Tag Change](https://www.airship.com/docs/guides/messaging/messages/sequences/triggers/#tag-change) in *Automation and Sequence triggers*.

Read more about data export and user matching in Mixpanel's
[Airship Set Up Guide](https://docs.mixpanel.com/docs/cohort-sync/integrations/airship).

## Requirements

The Mixpanel integration has the following requirements:

* **Accounts**
    1. Mixpanel
    1. Airship
        * Messaging
        * [Real-Time Data Streaming](https://www.airship.com/docs/reference/feature-packages/#data) — *Required for outbound integration only*
* **Airship project**
    * Recommended: Enable [named user](https://www.airship.com/docs/reference/glossary/#named_user) for non-mobile channels.

### User ID mapping

Airship and Mixpanel match users by the Airship [channel](https://www.airship.com/docs/reference/glossary/#channel_term) ID. Within Mixpanel, the channel ID is saved as one of the following user profile properties:

* **iOS**: `$ios_urban_airship_channel_id`
* **Android**: `$android_urban_airship_channel_id`

If you don't use the Mixpanel SDK, add these properties and set the values with the
Mixpanel API to match users by channel IDs.

If you would like to specify a value to match a Mixpanel user profile to a [named user](https://www.airship.com/docs/reference/glossary/#named_user), add
the `$airship_named_user` user property (the Airship SDK will not automatically declare it),
which will be sent when matching.

Users without `$airship_named_user` user property will instead have their `distinct_id`
sent to Airship named user system. This route is intended for implementations where the
same identifier value is used for both `distinct_id` (Mixpanel) and `named_user_id` (Airship).

## Inbound integration

To configure the inbound integration in the Airship dashboard, complete these steps:

1. Next to your project name, select the dropdown menu (), then **Settings**.
1. Under **Project settings**, select **Partner Integrations**.
1. Select **Mixpanel**.
1. Select **Configure** for the inbound integration and follow the onscreen instructions to:
	* Create a [tag group](https://www.airship.com/docs/reference/glossary/#tag_group) and an authentication token. Mixpanel uses the token to communicate with your project in Airship.
	* Configure the Airship integration in Mixpanel.

### Send Mixpanel cohorts to Airship as tags

After [configuring the Mixpanel inbound integration](#mixpanel-inbound-integration), you can use your Mixpanel cohorts to set tags on your audience, helping you organize and retarget your audience based on analytics information from Mixpanel. To have Mixpanel send selected cohorts, you need to *export* each cohort to your Airship integration.

To export a cohort, complete these steps in Mixpanel:

1. Go to **Data Management**, then **Cohorts**.
1. Select the more menu icon () for a cohort, then **Export to ...**, then **Airship**.
1. Specify if the cohort should be sent one time only or dynamically (at predefined intervals).

See also: [Mixpanel's Airship documentation](https://docs.mixpanel.com/docs/cohort-sync/integrations/airship).

## Outbound integration

Mixpanel library initialization requires a Mixpanel project token. See [Find Project Token](https://docs.mixpanel.com/docs/orgs-and-projects/managing-projects#find-your-project-tokens) to locate your token.

To set up the outbound integration, complete the following:

1. Configure your app to set the `mixpanel_distinct_id` on Airship events. See the Android and iOS setup sections below for more information.
1. Set up the RTDS integration in the Airship dashboard.

When you set up a Mixpanel RTDS integration, your events will contain a `mixpanel_distinct_id` key. This is the identifier Mixpanel uses to differentiate between unique events. As a fallback, you may want to set your Airship named user value to `mixpanel_distinct_id` to ensure that events are matched within Mixpanel.

### Set up RTDS for Android

[Mixpanel Android SDK Docs](https://developer.mixpanel.com/docs/android)
```java
// Initialize the Mixpanel library with your project token
MixpanelAPI mixpanel = MixpanelAPI.getInstance(context, "MIXPANEL_PROJECT_TOKEN");

// Get the Mixpanel distinct ID
String distinctId = mixpanel.getDistinctId();

// Add the distinct ID to the current associated identifiers
Airship.getAnalytics()
                .editAssociatedIdentifiers()
                .addIdentifier("mixpanel_distinct_id", distinctId)
                .apply();
```


### Set up RTDS for iOS Swift

[Mixpanel Swift SDK Docs](https://developer.mixpanel.com/docs/swift)

```swift
// Initialize the Mixpanel library with your project token
Mixpanel.initialize(token: "MIXPANEL_PROJECT_TOKEN")
let mixpanel = Mixpanel.mainInstance()

// Get the Mixpanel distinct ID
let distinctId = mixpanel.distinctId

// Add the distinct ID to the current associated identifiers
let identifiers = Airship.analytics.currentAssociatedDeviceIdentifiers()
identifiers.set(identifier: distinctId, key:"mixpanel_distinct_id")
Airship.analytics.associateDeviceIdentifiers(identifiers)
```


### Set up RTDS for iOS Objective-C

[Mixpanel Objective-C SDK Docs](https://developer.mixpanel.com/docs/ios)
```obj-c
// Initialize the Mixpanel library with your project token
Mixpanel *mixpanel = [Mixpanel sharedInstanceWithToken:@"MIXPANEL_PROJECT_TOKEN"];

// Get the Mixpanel distinct ID
NSString *distinctId = mixpanel.distinctId;

// Add the distinct ID to the current associated identifiers
UAAssociatedIdentifiers *identifiers = [UAirship.analytics currentAssociatedDeviceIdentifiers];
[identifiers setIdentifier:distinctId forKey:@"mixpanel_distinct_id"];
[UAirship.analytics associateDeviceIdentifiers:identifiers];
```


### Set up RTDS for React Native

[Mixpanel React Native SDK Docs](https://developer.mixpanel.com/docs/react-native)
```javascript
// Initialize the Mixpanel library with your project token
const mixpanel = await Mixpanel.init('MIXPANEL_PROJECT_TOKEN', true);

// Get the Mixpanel distinct ID
const distinctId = await mixpanel.getDistinctId();
// Add the distinct ID to the current associated identifiers
UrbanAirship.associateIdentifier("mixpanel_distinct_id", distinctId);
```



### Set up the Mixpanel RTDS integration in Airship

You will need your Mixpanel project token. To set up the RTDS integration in the Airship dashboard, complete these steps:

1. Next to your project name, select the dropdown menu (), then **Settings**.
1. Under **Project settings**, select **Partner Integrations**.
1. Select **Mixpanel**.
1. Select **Configure** for the outbound integration and follow the onscreen instructions to enter your Mixpanel project token and set the data residency region that matches your Mixpanel project: US, EU, or India.

### Event type mapping

In Mixpanel, you can find your events by type, prefixed with *Airship*, for example, *Airship First Opt-in* for the `"type": "FIRST_OPT_IN"` event. Because the `custom` event type differentiates between events by `name`, Mixpanel uses the event `name` for custom events (if the event has a name), in the format *Airship `body.name`*. The following table shows how Airship event types map to Mixpanel events:

| Airship Event | Mixpanel Event |
|---|---|
| `CLOSE`  |  `Airship Close` |
| `CONTROL` |  `Airship Control` |
| `CUSTOM`  |  `Airship` + `custom.name` (Example: `Airship Add To Cart`)<p>Defaults to `Airship Custom` if `body.name` is absent.|
| Email Bounce<sup>1</sup> | `Airship Bounce` |
| Email Click<sup>1</sub> | `Airship Click` |
| Email Delay<sup>1</sub> | `Airship Delay` |
| Email Delivery<sup>1</sub> | `Airship Delivery` |
| Email Injection<sup>1</sub> | `Airship Injection` |
| Email Open<sup>1</sub> | `Airship Open` |
| Email Unsubscribe<sup>1</sub> | `Airship Unsubscribe` |
| `FIRST_OPEN` |  `Airship First Open` |
| `FIRST_OPT_IN`  |  `Airship First Opt-in`  |
| `IN_APP_BUTTON_TAP` |  `Airship In-App Button Tap` |
| `IN_APP_EXPERIENCES` |  `Airship In-App Experiences` |
| `IN_APP_FORM_DISPLAY` |  `Airship In-App Form Display` |
| `IN_APP_FORM_RESULT` |  `Airship In-App Form Result` |
| `IN_APP_MESSAGE_DISPLAY` |  `Airship In-App Message Display` |
| `IN_APP_MESSAGE_EXPIRATION`  |  `Airship In-App Message Expiration` |
| `IN_APP_MESSAGE_RESOLUTION`  |   `Airship In-App Message Resolution`|
| `IN_APP_PAGE_SWIPE` |  `Airship In-App Page Swipe` |
| `IN_APP_PAGE_VIEW` |  `Airship In-App Page View` |
| `IN_APP_PAGER_COMPLETED` |  `Airship In-App Pager Completed` |
| `IN_APP_PAGER_SUMMARY` |  `Airship In-App Pager Completed` |
| `LOCATION`  |  `Airship Location` |
| `MOBILE_ORIGINATED` | `Airship Mobile Originated` |
| `OPEN`  |  `Airship Open` |
| `REGION` |  `Airship Region` |
| `RICH_DELETE`  |  `Airship Rich Delete` |
| `RICH_DELIVERY`  |  `Airship Rich Delivery` |
| `RICH_READ`  |  `Airship Rich Read` |
| `SCREEN_VIEWED` | `Airship Screen Viewed`  |
| `SEND`  |  `Airship Send` |
| `SEND_ABORTED` |  `Airship Send Aborted` |
| `SEND_REJECTED` |  `Airship Send Rejected` |
| `SHORT_LINK_CLICKED` | `Airship Short Link Click` |
| SMS Delivery Report — Aborted<sup>2</sub> | `Airship SMS Delivery Aborted` |
| SMS Delivery Report — Delivered<sup>2</sub> | `Airship SMS Delivered` |
| SMS Delivery Report — Dispatched<sup>2</sub> | `Airship SMS Delivery Dispatched` |
| SMS Delivery Report — Expired<sup>2</sub> | `Airship SMS Delivery Expired` |
| SMS Delivery Report — Failed<sup>2</sub> | `Airship SMS Delivery Failed` |
| SMS Delivery Report — Rejected<sup>2</sub> | `Airship SMS Delivery Rejected` |
| SMS Delivery Report — Undeliverable<sup>2</sub> | `Airship SMS Delivery Undeliverable` |
| SMS Delivery Report — Unknown<sup>2</sub> | `Airship SMS Delivery Unknown` |
| `SUBSCRIPTION` | `Airship Subscription` — indicates change in email subscription status or values |
| `WEB_CLICK` | `Airship Web Click` |
| `WEB_SESSION` | `Airship Web Session` |
| `UNINSTALL` |  `Airship Uninstall` |

<sup>1. Email delivery report events are `CUSTOM` type events with a `body.name` property indicating the delivery status of an email. Mixpanel uses the `body.name` key rather than the `type` key to better represent the event.</sup><br>
<sup>2. SMS Delivery reports are `CUSTOM` type events that use the `body.name` property to represent the status of your SMS delivery (as reported by the last-mile provider).</sup>

### Event property mapping

The following table shows how Airship event properties map to Mixpanel event properties:

| Airship Event Property  |  Mixpanel Event Property |
|---|---|
| `body.event_type` | `Specific Event Type` (The event `type` property is already called `Event Type`.) |
| `body.identifiers.msisdn` | `MSISDN` |
| `body.identifiers.sender` | `Sender` |
| `body.properties.inbound_message` | `Inbound Message` |
| `body.properties.keyword` | `Keyword` |
| `body.properties.outbound_message` | `Outbound Message` |
|  `device.amazon_channel` |  `Amazon Channel ID` |
|  `device.android_channel` |  `Android Channel ID` |
|  `device.attributes.app_package_name` |  `App Package Name` |
|  `device.attributes.app_version` |  `App Version` |
|  `device.attributes.background_push_enabled` |  `Background Push Notifications Enabled` |
|  `device.attributes.device_model` |  `Model` |
|  `device.attributes.device_os` |  `OS Version` |
|  `device.attributes.iana_timezone` |  `Timezone` |
|  `device.attributes.locale_country_code` |  `Country Code` |
|  `device.attributes.locale_language_code` |  `Language Code` |
|  `device.attributes.locale_timezone` |  `Timezone Offset` |
|  `device.attributes.locale_variant` |  `Language Variant` |
|  `device.attributes.location_enabled` |  `Location Services Enabled` |
|  `device.attributes.location_permission` |  `Location Permission` |
|  `device.attributes.push_opt_in` |  `Opted Into Push Notifications` |
|  `device.attributes.ua_sdk_version` |  `Airship SDK Version` |
| `device.attributes.web_browser_name` | `Browser` |
| `device.attributes.web_browser_type` | `Web Browser Type` |
| `device.attributes.web_browser_version` | `Web Browser Version` |
| `device.attributes.web_user_agent_string` | `Web User Agent String` |
|  `device.channel` |  `Channel ID` |
| `device.delivery_address` | `Delivery Address` |
|  `device.device_type` |  `Device Type` |
|  `device.identifiers.AA_visitorID`  |  `Adobe Visitor ID` |
| `device.identifiers.address` | `Email Address` |
|  `device.identifiers.com.urbanairship.aaid` |  `Android/Amazon Ad ID` |
|  `device.identifiers.com.urbanairship.gimbal.aii` |  `Gimbal App Instance ID` |
|  `device.identifiers.com.urbanairship.limited_ad_tracking_enabled` |  `Limited Ad Tracking Enabled` |
|  `device.identifiers.com.urbanairship.vendor` |  `Apple Vendor ID` |
|  `device.identifiers.GA_CID` |  `Google Analytics Client ID`|
|  `device.identifiers.IDFA` |  `IDFA` |
|  `device.ios_channel` |  `iOS Channel ID` |
|  `device.named_user_id` |  `Named User ID` |
|  `id` |  `Event ID` |
|  `offset` |  `Event Offset` |
|  `occurred` |  `Time` |
|  `type` |  `Event Type` |

### Tag change event property mapping

When Airship sends a tag change event to Mixpanel, Mixpanel reflects the `current` tags as event properties. Mixpanel uses the tag group as the property and the tags in the group as the value.

**Example tag change event**

```json
{
  "id": "00000169-4a14-67b2-1ddd-d9e733622c3a",
  "occurred": "2020-06-23T19:00:45.106Z",
  "offset": "1000001260057",
  "processed": "2020-06-23T19:00:47.094Z",
  "type": "TAG_CHANGE",
  "device": {
    "ios_channel": "1ef235f0-03d5-1384-893e-a19b5cd0d110",
    "channel": "1ef235f0-03d5-1384-893e-a19b5cd0d110",
    "device_type": "IOS",
   },
  "body":{
    "add": {
        "crm": [
          "partner",
          "active"
        ],
        "loyalty": [
          "silver_member"
        ]
    },
    "current": {
        "crm": [
          "partner",
          "active",
          "new_user"
        ],
        "loyalty": [
          "silver_member",
          "special_offers"
        ],
        "device": [
          "san_francisco",
          "sports"
        ]
      }
    },
  "type": "TAG_CHANGE"
}
```


From the example above, Mixpanel maps tag groups and tags as follows:

| Airship Event Property  |  Mixpanel User Property |  Value |
|---|---|---|
|  `body.current.crm` | `Airship crm`  | `["partner", "active", "new_user"]`  |
| `body.current.loyalty`  |  `Airship loyalty` | `["silver_member", "special_offers"]`  |
| `body.current.device`  |  `Airship device` |  `["san_francisco", "sports"]` |
