diff --git a/website/docs/integrations/mixpanel.mdx b/website/docs/integrations/mixpanel.mdx new file mode 100644 index 000000000..4473dfedd --- /dev/null +++ b/website/docs/integrations/mixpanel.mdx @@ -0,0 +1,270 @@ +--- +id: mixpanel +title: Mixpanel - Monitor your feature flag change events and feature flag analytics +description: ConfigCat Mixpanel integration. This is a step-by-step guide on how to connect the ConfigCat feature flag service events to Mixpanel. +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; +import CodeBlock from '@theme/CodeBlock'; + +## Overview + +There are two available integration oppurtunities between ConfigCat and Mixpanel: +- [Monitoring your feature flag change events in Mixpanel with Annotations](#annotations) +- [Sending feature flag evaluation analytics to Mixpanel Experiments](#experiments) + +## Monitoring your feature flag change events in Mixpanel with Annotations {#annotations} + +Ensures that every setting change in ConfigCat is sent to Mixpanel as an Annotation. + +Mixpanel Annotation + +### Installation + +1. Have a Mixpanel account. +2. Create a Service account that has at least an Analyst role. mixpanel_service_Account +3. Open the integrations tab on the ConfigCat Dashboard. +4. Click on Mixpanel's CONNECT button and set your Mixpanel Service Account's Username, Secret, and your Project ID. +5. OPTIONAL - Set the proper server of your Mixpanel account. More about Mixpanel servers. +6. You're all set. Go ahead and make some changes on your feature flags then check your annotations in Mixpanel. + +### Un-installation + +1. Open the integrations tab on the ConfigCat Dashboard. +2. Click on Mixpanel's DISCONNECT button. + +### Annotation details + +Every annotation sent to Mixpanel by ConfigCat has: + +- **Integration ID:** configcat. +- **Date:** When the change happened +- **Description:** A brief summary of the change. + +## Sending feature flag evaluation analytics to Mixpanel Experiments {#experiments} + +Ensures that feature flag evaluations are logged into Mixpanel Experiments. With this integration, you can have advanced analytics about your feature flag usages, A/B test results. + +### Setup + +1. Install the ConfigCat and Mixpanel SDKs to your application. +2. Configure the ConfigCat SDK with your ConfigCat SDK key and the Mixpanel SDK with your Mixpanel token. +3. In your code, subscribe to the `flagEvaluated` hook during the ConfigCat SDK initialization and send feature flag evaluation data to Mixpanel experiments. +There are 2 different approaches that you can use to send feature flag analytics events to Mixpanel. + - You can send an `$experiment_started` tracking event when the feature flag is evaluated. + This way you can create custom reports based on feature flag evaluation events and use the Experiments feature in Mixpanel. + - You can use the Identify API in Mixpanel to enrich all your events with feature flag metadata. This way you can easily group/filter your existing Mixpanel events by feature flag evaluations. + +Code samples: + + +```js +const configCatClient = configcat.getClient("#YOUR_SDK_KEY", PollingMode.AutoPoll, { + setupHooks: (hooks) => + hooks.on('flagEvaluated', evaluationDetails => { + // Send an `$experiment_started` event. + mixpanel.track('$experiment_started', + { + 'Experiment name': evaluationDetails.key, + 'Variant name': evaluationDetails.value, + 'Variation ID': evaluationDetails.variationId + }); + + // Use the identify API. + mixpanel.people.set({ ["configcat_" + evaluationDetails.key]: evaluationDetails.value }); + }), +}); +``` + + + +```tsx + + hooks.on('flagEvaluated', evaluationDetails => { + // Send an `$experiment_started` event. + mixpanel.track('$experiment_started', + { + 'Experiment name': evaluationDetails.key, + 'Variant name': evaluationDetails.value, + 'Variation ID': evaluationDetails.variationId + }); + + // Use the identify API. + mixpanel.people.set({ ["configcat_" + evaluationDetails.key]: evaluationDetails.value }); + }), + }} +> + +``` + + + +```python +def on_flag_evaluated(evaluation_details): + # Send an `$experiment_started` event. + mixpanel.track(evaluation_details.user.get_identifier(), '$experiment_started', { + 'Experiment name': evaluation_details.key, + 'Variant name': evaluation_details.value, + 'Variation ID': evaluation_details.variation_id + }) + + # Use the identify API. + mixpanel.people_set(evaluation_details.user.get_identifier(), { + f'configcat_{evaluationDetails.key}': evaluation_details.value, + }) + pass + +client = configcatclient.get('#YOUR-SDK-KEY#', + ConfigCatOptions( + hooks=Hooks(on_flag_evaluated=on_flag_evaluated) + ) +) +``` + + + +```ruby +def on_flag_evaluated(evaluation_details): + # Send an `$experiment_started` event. + mixpanel.track(evaluation_details.user.get_identifier(), "$experiment_started", { + "Experiment name": evaluation_details.key, + "Variant name": evaluation_details.value, + "Variation ID": evaluation_details.variation_id + }) + + # Use the identify API. + mixpanel.people.set(evaluation_details.user.get_identifier(), { + "configcat_#{evaluationDetails.key}" => evaluation_details.value, + }) +end + +client = ConfigCat.get("#YOUR-SDK-KEY#", + ConfigCat::ConfigCatOptions.new( + hooks: ConfigCat::Hooks.new(on_flag_evaluated: method(:on_flag_evaluated)) + ) +) +``` + + + +```go +client := configcat.NewCustomClient(configcat.Config{SDKKey: "#YOUR-SDK-KEY#", + Hooks: &configcat.Hooks{OnFlagEvaluated: func(details *EvaluationDetails) { + // Send an `$experiment_started` event. + err := mixpanel.Track(ctx, []*mixpanel.Event{ + mixpanel.NewEvent("$experiment_started", details.Data.User.(*UserData).Identifier, map[string]any{ + "Experiment name": details.Data.Key, + "Variant name": details.Value, + "Variation ID": details.Data.VariationID, + }), + }) + + // Use the identify API. + err := mixpanel.PeopleSet(ctx, + []*mixpanel.PeopleProperties{ + mixpanel.NewPeopleProperties(details.Data.User.(*UserData).Identifier, map[string]any{ + "configcat_" + details.Data.Key: details.Value, + }) + }, + ) + }}}) +``` + + + +```java +ConfigCatClient client = ConfigCatClient.get("#YOUR-SDK-KEY#", options -> { + options.hooks().addOnFlagEvaluated(details -> { + // Send an `$experiment_started` event. + JSONObject eventProps = new JSONObject(); + eventProps.put("Experiment name", details.getKey()); + eventProps.put("Variant name", details.getValue()); + eventProps.put("Variation ID", details.getVariationId()); + JSONObject event = messageBuilder.event(details.getUser().getIdentifier(), "$experiment_started", eventProps); + mixpanel.sendMessage(event); + + // Use the identify API. + JSONObject userProps = new JSONObject(); + userProps.put("configcat_" + details.getKey(), details.getValue()); + JSONObject updateUser = messageBuilder.set(details.getUser().getIdentifier(), userProps); + mixpanel.sendMessage(updateUser); + }); +}); +``` + + + +```java +ConfigCatClient client = ConfigCatClient.get("#YOUR-SDK-KEY#", options -> { + options.hooks().addOnFlagEvaluated(details -> { + // Send an `$experiment_started` event. + JSONObject eventProps = new JSONObject(); + eventProps.put("Experiment name", details.getKey()); + eventProps.put("Variant name", details.getValue()); + eventProps.put("Variation ID", details.getVariationId()); + mixpanel.track("$experiment_started", eventProps); + + // Use the identify API. + mixpanel.getPeople().set("configcat_" + details.getKey(), details.getValue()); + }); +}); +``` + + + +```swift +let client = ConfigCatClient.get(sdkKey: "#YOUR-SDK-KEY#") { options in + options.hooks.addOnFlagEvaluated { details in + // Send an `$experiment_started` event. + Mixpanel.mainInstance().track(event:"$experiment_started", properties: [ + "Experiment name": details.key, + "Variant name": details.value, + "Variation ID": details.variationId, + ]) + + // Use the identify API. + let keyProperty = "configcat_" + details.Data.Key; + Mixpanel.mainInstance().people.set(properties: [ keyProperty: details.value]) + } +} +``` + + + +The documentation only shows code examples to those languages that Mixpanel natively supports and has an official SDK, +but you can use this integration in other languages as well with sending an event to Mixpanel with a third-party SDK or with using the Mixpanel's Track Events API. +You can subscribe to the FlagEvaluated hook in the ConfigCat SDK and send an Event to Mixpanel with the `$experiment_started` event name and the following event properties: +1. `Experiment name`: the feature flag's key from the FlagEvaluated hook's EvaluationDetails +2. `Variant name`: the evalated feature flag's value or the variationId from the FlagEvaluated hook's EvaluationDetails +3. `Variant name`: the evalated feature flag's value or the variationId from the FlagEvaluated hook's EvaluationDetails +4. `distinct_id` (optional): in case you are using the tracking in a backend component or you don't identify all your event sendings to Mixpanel with user details, +you have to send the distinct_id property as well to identify your user. You can use the User object's Identifier property from the FlagEvaluated hook or a value that best describes your user. + + + + +:::note +If you are using Text feature flags with long text values (e.g. JSON values), you can send the `variationId` as the `Variant name` to Mixpanel instead of the `value`. +The `variationId` is a hashed version of the feature flag value and you can access the `variationId` on the ConfigCat Dashboard after turning on the _Show VariationIDs to support A/B testing_ +Product preference. +::: + +4. Deploy your application and wait for feature flag evaluations to happen so Experiments in Mixpanel could be populated. + +### Usage with Experiments +Check your Experiments page in Mixpanel, select your feature flag as the Experiment. +Mixpanel Experiments report + +### Usage with Insights report +If you don't have access to the Experiments feature in Mixpanel, you can create a custom Insights report based on the `Experiment Started` event. +You can filter for your feature flag keys with the `Experiment name` property and visualize the different variants by using the `Variant name` property as a Breakdown. Example: +Mixpanel Insights report + +### Usage with enriched user properties for your custom events. +If you use the Identify API approach, you'll be able to use the feature flag evaluation data in your current reports. Example with a Breakdown: +Mixpanel Insights report with enriched data \ No newline at end of file diff --git a/website/docs/sdk-reference/go.mdx b/website/docs/sdk-reference/go.mdx index 73a707bfa..5cc4b248f 100644 --- a/website/docs/sdk-reference/go.mdx +++ b/website/docs/sdk-reference/go.mdx @@ -348,7 +348,7 @@ You can subscribe to these events on SDK initialization: client := configcat.NewCustomClient(configcat.Config{SDKKey: "#YOUR-SDK-KEY#", Hooks: &configcat.Hooks{OnFlagEvaluated: func(details *EvaluationDetails) { /* handle the event */ - }}) + }}}) ``` ## Online / Offline mode diff --git a/website/sidebars.ts b/website/sidebars.ts index 5a1cebf5d..01e40f687 100644 --- a/website/sidebars.ts +++ b/website/sidebars.ts @@ -176,6 +176,7 @@ const sidebars: SidebarsConfig = { { type: 'doc', id: 'integrations/datadog', label: 'Datadog' }, { type: 'doc', id: 'integrations/github', label: 'GitHub Action' }, { type: 'doc', id: 'integrations/jira', label: 'Jira Cloud Plugin' }, + { type: 'doc', id: 'integrations/mixpanel', label: 'Mixpanel' }, { type: 'doc', id: 'integrations/monday', label: 'monday.com' }, { type: 'doc', id: 'integrations/slack', label: 'Slack' }, { type: 'doc', id: 'integrations/terraform', label: 'Terraform' }, diff --git a/website/src/pages/index.js b/website/src/pages/index.js index 86268690b..d8fa3b8eb 100644 --- a/website/src/pages/index.js +++ b/website/src/pages/index.js @@ -97,6 +97,7 @@ const features = [ { url: 'integrations/bitrise', title: 'Bitrise Step' }, { url: 'integrations/terraform', title: 'Terraform' }, { url: 'integrations/amplitude', title: 'Amplitude' }, + { url: 'integrations/mixpanel', title: 'Mixpanel' }, { url: 'integrations/zoho-flow', title: 'Zoho Flow' }, { url: 'integrations/vscode', title: 'Visual Studio Code' }, { diff --git a/website/static/assets/mixpanel/annotation.png b/website/static/assets/mixpanel/annotation.png new file mode 100644 index 000000000..7340675cc Binary files /dev/null and b/website/static/assets/mixpanel/annotation.png differ diff --git a/website/static/assets/mixpanel/enrichment.png b/website/static/assets/mixpanel/enrichment.png new file mode 100644 index 000000000..f3fd1ff12 Binary files /dev/null and b/website/static/assets/mixpanel/enrichment.png differ diff --git a/website/static/assets/mixpanel/experiments.png b/website/static/assets/mixpanel/experiments.png new file mode 100644 index 000000000..321993919 Binary files /dev/null and b/website/static/assets/mixpanel/experiments.png differ diff --git a/website/static/assets/mixpanel/insights.png b/website/static/assets/mixpanel/insights.png new file mode 100644 index 000000000..ac5c57710 Binary files /dev/null and b/website/static/assets/mixpanel/insights.png differ diff --git a/website/static/assets/mixpanel/service_account.png b/website/static/assets/mixpanel/service_account.png new file mode 100644 index 000000000..dfe793b57 Binary files /dev/null and b/website/static/assets/mixpanel/service_account.png differ diff --git a/website/versioned_docs/version-V1/integrations/mixpanel.mdx b/website/versioned_docs/version-V1/integrations/mixpanel.mdx new file mode 100644 index 000000000..4473dfedd --- /dev/null +++ b/website/versioned_docs/version-V1/integrations/mixpanel.mdx @@ -0,0 +1,270 @@ +--- +id: mixpanel +title: Mixpanel - Monitor your feature flag change events and feature flag analytics +description: ConfigCat Mixpanel integration. This is a step-by-step guide on how to connect the ConfigCat feature flag service events to Mixpanel. +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; +import CodeBlock from '@theme/CodeBlock'; + +## Overview + +There are two available integration oppurtunities between ConfigCat and Mixpanel: +- [Monitoring your feature flag change events in Mixpanel with Annotations](#annotations) +- [Sending feature flag evaluation analytics to Mixpanel Experiments](#experiments) + +## Monitoring your feature flag change events in Mixpanel with Annotations {#annotations} + +Ensures that every setting change in ConfigCat is sent to Mixpanel as an Annotation. + +Mixpanel Annotation + +### Installation + +1. Have a Mixpanel account. +2. Create a Service account that has at least an Analyst role. mixpanel_service_Account +3. Open the integrations tab on the ConfigCat Dashboard. +4. Click on Mixpanel's CONNECT button and set your Mixpanel Service Account's Username, Secret, and your Project ID. +5. OPTIONAL - Set the proper server of your Mixpanel account. More about Mixpanel servers. +6. You're all set. Go ahead and make some changes on your feature flags then check your annotations in Mixpanel. + +### Un-installation + +1. Open the integrations tab on the ConfigCat Dashboard. +2. Click on Mixpanel's DISCONNECT button. + +### Annotation details + +Every annotation sent to Mixpanel by ConfigCat has: + +- **Integration ID:** configcat. +- **Date:** When the change happened +- **Description:** A brief summary of the change. + +## Sending feature flag evaluation analytics to Mixpanel Experiments {#experiments} + +Ensures that feature flag evaluations are logged into Mixpanel Experiments. With this integration, you can have advanced analytics about your feature flag usages, A/B test results. + +### Setup + +1. Install the ConfigCat and Mixpanel SDKs to your application. +2. Configure the ConfigCat SDK with your ConfigCat SDK key and the Mixpanel SDK with your Mixpanel token. +3. In your code, subscribe to the `flagEvaluated` hook during the ConfigCat SDK initialization and send feature flag evaluation data to Mixpanel experiments. +There are 2 different approaches that you can use to send feature flag analytics events to Mixpanel. + - You can send an `$experiment_started` tracking event when the feature flag is evaluated. + This way you can create custom reports based on feature flag evaluation events and use the Experiments feature in Mixpanel. + - You can use the Identify API in Mixpanel to enrich all your events with feature flag metadata. This way you can easily group/filter your existing Mixpanel events by feature flag evaluations. + +Code samples: + + +```js +const configCatClient = configcat.getClient("#YOUR_SDK_KEY", PollingMode.AutoPoll, { + setupHooks: (hooks) => + hooks.on('flagEvaluated', evaluationDetails => { + // Send an `$experiment_started` event. + mixpanel.track('$experiment_started', + { + 'Experiment name': evaluationDetails.key, + 'Variant name': evaluationDetails.value, + 'Variation ID': evaluationDetails.variationId + }); + + // Use the identify API. + mixpanel.people.set({ ["configcat_" + evaluationDetails.key]: evaluationDetails.value }); + }), +}); +``` + + + +```tsx + + hooks.on('flagEvaluated', evaluationDetails => { + // Send an `$experiment_started` event. + mixpanel.track('$experiment_started', + { + 'Experiment name': evaluationDetails.key, + 'Variant name': evaluationDetails.value, + 'Variation ID': evaluationDetails.variationId + }); + + // Use the identify API. + mixpanel.people.set({ ["configcat_" + evaluationDetails.key]: evaluationDetails.value }); + }), + }} +> + +``` + + + +```python +def on_flag_evaluated(evaluation_details): + # Send an `$experiment_started` event. + mixpanel.track(evaluation_details.user.get_identifier(), '$experiment_started', { + 'Experiment name': evaluation_details.key, + 'Variant name': evaluation_details.value, + 'Variation ID': evaluation_details.variation_id + }) + + # Use the identify API. + mixpanel.people_set(evaluation_details.user.get_identifier(), { + f'configcat_{evaluationDetails.key}': evaluation_details.value, + }) + pass + +client = configcatclient.get('#YOUR-SDK-KEY#', + ConfigCatOptions( + hooks=Hooks(on_flag_evaluated=on_flag_evaluated) + ) +) +``` + + + +```ruby +def on_flag_evaluated(evaluation_details): + # Send an `$experiment_started` event. + mixpanel.track(evaluation_details.user.get_identifier(), "$experiment_started", { + "Experiment name": evaluation_details.key, + "Variant name": evaluation_details.value, + "Variation ID": evaluation_details.variation_id + }) + + # Use the identify API. + mixpanel.people.set(evaluation_details.user.get_identifier(), { + "configcat_#{evaluationDetails.key}" => evaluation_details.value, + }) +end + +client = ConfigCat.get("#YOUR-SDK-KEY#", + ConfigCat::ConfigCatOptions.new( + hooks: ConfigCat::Hooks.new(on_flag_evaluated: method(:on_flag_evaluated)) + ) +) +``` + + + +```go +client := configcat.NewCustomClient(configcat.Config{SDKKey: "#YOUR-SDK-KEY#", + Hooks: &configcat.Hooks{OnFlagEvaluated: func(details *EvaluationDetails) { + // Send an `$experiment_started` event. + err := mixpanel.Track(ctx, []*mixpanel.Event{ + mixpanel.NewEvent("$experiment_started", details.Data.User.(*UserData).Identifier, map[string]any{ + "Experiment name": details.Data.Key, + "Variant name": details.Value, + "Variation ID": details.Data.VariationID, + }), + }) + + // Use the identify API. + err := mixpanel.PeopleSet(ctx, + []*mixpanel.PeopleProperties{ + mixpanel.NewPeopleProperties(details.Data.User.(*UserData).Identifier, map[string]any{ + "configcat_" + details.Data.Key: details.Value, + }) + }, + ) + }}}) +``` + + + +```java +ConfigCatClient client = ConfigCatClient.get("#YOUR-SDK-KEY#", options -> { + options.hooks().addOnFlagEvaluated(details -> { + // Send an `$experiment_started` event. + JSONObject eventProps = new JSONObject(); + eventProps.put("Experiment name", details.getKey()); + eventProps.put("Variant name", details.getValue()); + eventProps.put("Variation ID", details.getVariationId()); + JSONObject event = messageBuilder.event(details.getUser().getIdentifier(), "$experiment_started", eventProps); + mixpanel.sendMessage(event); + + // Use the identify API. + JSONObject userProps = new JSONObject(); + userProps.put("configcat_" + details.getKey(), details.getValue()); + JSONObject updateUser = messageBuilder.set(details.getUser().getIdentifier(), userProps); + mixpanel.sendMessage(updateUser); + }); +}); +``` + + + +```java +ConfigCatClient client = ConfigCatClient.get("#YOUR-SDK-KEY#", options -> { + options.hooks().addOnFlagEvaluated(details -> { + // Send an `$experiment_started` event. + JSONObject eventProps = new JSONObject(); + eventProps.put("Experiment name", details.getKey()); + eventProps.put("Variant name", details.getValue()); + eventProps.put("Variation ID", details.getVariationId()); + mixpanel.track("$experiment_started", eventProps); + + // Use the identify API. + mixpanel.getPeople().set("configcat_" + details.getKey(), details.getValue()); + }); +}); +``` + + + +```swift +let client = ConfigCatClient.get(sdkKey: "#YOUR-SDK-KEY#") { options in + options.hooks.addOnFlagEvaluated { details in + // Send an `$experiment_started` event. + Mixpanel.mainInstance().track(event:"$experiment_started", properties: [ + "Experiment name": details.key, + "Variant name": details.value, + "Variation ID": details.variationId, + ]) + + // Use the identify API. + let keyProperty = "configcat_" + details.Data.Key; + Mixpanel.mainInstance().people.set(properties: [ keyProperty: details.value]) + } +} +``` + + + +The documentation only shows code examples to those languages that Mixpanel natively supports and has an official SDK, +but you can use this integration in other languages as well with sending an event to Mixpanel with a third-party SDK or with using the Mixpanel's Track Events API. +You can subscribe to the FlagEvaluated hook in the ConfigCat SDK and send an Event to Mixpanel with the `$experiment_started` event name and the following event properties: +1. `Experiment name`: the feature flag's key from the FlagEvaluated hook's EvaluationDetails +2. `Variant name`: the evalated feature flag's value or the variationId from the FlagEvaluated hook's EvaluationDetails +3. `Variant name`: the evalated feature flag's value or the variationId from the FlagEvaluated hook's EvaluationDetails +4. `distinct_id` (optional): in case you are using the tracking in a backend component or you don't identify all your event sendings to Mixpanel with user details, +you have to send the distinct_id property as well to identify your user. You can use the User object's Identifier property from the FlagEvaluated hook or a value that best describes your user. + + + + +:::note +If you are using Text feature flags with long text values (e.g. JSON values), you can send the `variationId` as the `Variant name` to Mixpanel instead of the `value`. +The `variationId` is a hashed version of the feature flag value and you can access the `variationId` on the ConfigCat Dashboard after turning on the _Show VariationIDs to support A/B testing_ +Product preference. +::: + +4. Deploy your application and wait for feature flag evaluations to happen so Experiments in Mixpanel could be populated. + +### Usage with Experiments +Check your Experiments page in Mixpanel, select your feature flag as the Experiment. +Mixpanel Experiments report + +### Usage with Insights report +If you don't have access to the Experiments feature in Mixpanel, you can create a custom Insights report based on the `Experiment Started` event. +You can filter for your feature flag keys with the `Experiment name` property and visualize the different variants by using the `Variant name` property as a Breakdown. Example: +Mixpanel Insights report + +### Usage with enriched user properties for your custom events. +If you use the Identify API approach, you'll be able to use the feature flag evaluation data in your current reports. Example with a Breakdown: +Mixpanel Insights report with enriched data \ No newline at end of file diff --git a/website/versioned_docs/version-V1/sdk-reference/go.mdx b/website/versioned_docs/version-V1/sdk-reference/go.mdx index 3c0346872..cd6917939 100644 --- a/website/versioned_docs/version-V1/sdk-reference/go.mdx +++ b/website/versioned_docs/version-V1/sdk-reference/go.mdx @@ -311,7 +311,7 @@ You can subscribe to these events on SDK initialization: client := configcat.NewCustomClient(configcat.Config{SDKKey: "#YOUR-SDK-KEY#", Hooks: &configcat.Hooks{OnFlagEvaluated: func(details *EvaluationDetails) { /* handle the event */ - }}) + }}}) ``` ## Online / Offline mode diff --git a/website/versioned_sidebars/version-V1-sidebars.json b/website/versioned_sidebars/version-V1-sidebars.json index 701fe5761..f3f6626b6 100644 --- a/website/versioned_sidebars/version-V1-sidebars.json +++ b/website/versioned_sidebars/version-V1-sidebars.json @@ -203,6 +203,11 @@ "id": "integrations/jira", "label": "Jira Cloud Plugin" }, + { + "type": "doc", + "id": "integrations/mixpanel", + "label": "Mixpanel" + }, { "type": "doc", "id": "integrations/monday",