Skip to main content

Notifications

Announcements

No record found.

Surface CI-D Customer Profile Insights in a MDA form through a Canvas App

Introduction

Part of a broader blog post series, this article will guide you through the creation of a Canvas App where you can fully customize both the content and the look-and-feel of the Dynamics 365 Customer Insights (CI-D) information you want to display in the context of your Contact form.

This capability relies on CustomerId Backstamping being set up and operational between CI-D and Dataverse, so check the previous article in the series if you want to know more about this prerequisite.

A sample Canvas App, dynamically displaying CI-D Customer Profile Segment Membership, can be downloaded here from GitHub, ready to be embedded in a Contact Model-Driven App (MDA) form for any Dynamics 365 App:


Fig. 1. - CI-D Customer Profile Segment Membership in Dynamics 365 Customer Insights - Journeys (CI-J) Contact form

Once imported, you can the get the App ID of the Canvas App from its "details" page, and use this App ID to embed it in your MDA form by configuring a Canvas app component: 


Fig. 2. - Embedding an existing Canvas App in the CI-J Contact MDA form

The rest of this article will give you a walkthrough of how this Canvas App was build, the associated prerequisites to allow its embedding in a MDA Contact form, and an introduction to understand the CI-D Dataverse tables model and relationships.

Dataverse Tables Model and Relationships

In the previous article in the series, we described how CI-D Customer Profiles Attributes could be used directly in a MDA Quick View form of the CustomerProfile table, and then embedded in a Contact MDA form.

On the other hand, Insights related to a CustomerProfile, such as measures, predictions, segment membership, etc. are not directly in the CustomerProfile table, but rather each in its own table having their own CustomerId lookup column to the CustomerProfile. This is where Canvas Apps will kick-in to allow full customization and navigating to the required table.



Fig. 3. - Relationships between the CustomerProfile table and some other tables as an example

Insights related to a CustomerProfile, such as measures, predictions, segment membership, etc. are not directly in the CustomerProfile table, but rather each in its own table having their own CustomerId lookup column to the CustomerProfile.
Note that while these lookups to the CustomerProfile table are technically defined in product as Many:1 relationships, they may be functionally 1:1 relationships:
  • 1 CustomerProfile record to 1 CustomerMeasure record.
  • 1 CustomerProfile to 1 SegmentMembership record.
  • 1 CustomerProfile record to potentially Many Prediction records (one record per defined model).


Fig. 4. - Example of 1 CustomerProfile CustomerId for 2 Prediction records

Several of these tables will store insight data in one column as a Json payload, requiring some parsing to be used and displayed:


Fig. 5. - Example of 1 CustomerProfile CustomerId for 1 CustomerMeasure record, storing several “customer attribute measures” and their value in the same Measures column as a Json payload

When you opt-in to hydrate specific measures, they each get their own table, named as the measure, with one column named as the defined calculation:


Fig. 6. - Example of a measure hydrated to its own table. The measure is named Purchases and contains two calculations: TotalAmount and AvgAmount

It is recommended to define Customer Measures as their own tables as shown in Fig. 6. rather that as attributes all going into the CustomerMeasure table as shown in Fig. 5. 

This way, it will be easier to consume each measure individually when building a Canvas App, and these measures will also be available when building a Contact segment in Dynamics 365 Customer Insights - Journeys.


Note that as soon as you start using a Customer Measure with its own table in a Canvas App, this will create a dependency in Dataverse which will prevent you from deleting the measure in CI-D until you have removed that dependency first. This mechanism, native to Dataverse to avoid breaking dependent downstream processes or customizations, is very similar that the one detailed for Customer Profiles Attributes in the "Managing Dependencies" section in the previous article in the series.

With all that in mind, it is critical to gain a good understanding of the specificities of each table you want to use before starting using it in any customization.

Canvas App Embedding Prerequisites

To be embedded in a Model Driven App form, such as the Contact form, a Canvas App need to have the “ModelDrivenFormIntegration” control.

This control is only made available when the Canvas app is created from the classic designer of a Model Driven App; the modern designer can only embed a pre-existing Canvas App that already has the “ModelDrivenFormIntegration” control, dedicated to re-use scenarios, such as embedding the sample provided in this article for instance.

Here are the steps to achieve this integration:


Fig. 7. - Create a section for the Canvas App, but do not use the “Canvas app” component which is only useful if you want to embed a Canvas App you already created for embedding and that has the prerequisite “ModelDrivenFormIntegration” control


Fig. 8. - Switch to classic


Fig. 9. - Add a field to the new section, and double click on it to open the “Field Properties” dialog



Fig. 10. - Click on “Add Control…” from the “Controls” tab


Fig. 11. - Select “Canvas app” and click on “Add”


Fig. 12. - Click on “Customize” to create the embedded canvas app


Fig. 13. - A Canvas App with the “ModelDrivenFormIntegration” control is created

For this Canvas App to integrate nicely and be responsive within the form we are recommending a few steps and settings:
  • Start by deleting the default “Form1” that was created.
  • Go to “Settings,” and setup “Display” properties as per Fig. 14. below.
  • Select the “App” and from the “Advanced” properties tab, set the MinScreenHeight and MinScreenWidth properties to “App.Height” and “App.Width” respectively as per Fig. 15. below.
  • Rename the default screen from “FormScreen” to your preferred name, we will be using “MyScreen” here for this article purpose.
  • Select the “Screen” (i.e., “MyScreen”) and from the “Advanced” properties tab, set the Height and Width properties based on the App ones as per Fig. 16. below.
  • Save and Publish the Canvas App


Fig. 14 - Canvas App custom display settings for best integration


Fig. 15. - App advanced properties for best integration and responsiveness


Fig. 16. - Screen advanced properties for best integration and responsiveness


Now, going back to the Model Driven App form “classic” designer, let’s finish validating the integration.



Fig. 17. - Going back to the Model Driven App, the Canvas App “App ID” should be populated

If the App ID is not automatically populated, click on the pencil icon and that should open a new dialog and refresh the values. The App ID can also be found from the details page of your Canvas App once saved.
To get things as clean as possible in the form, edit it again in the “modern” designer and simply replace the placeholder field with a plain Canvas App component now that we have an App ID to provide.



Fig. 18. - Cleaning the form by directly re-introducing a Canvas app component instead of the placeholder field and its custom control. Whenever adding or editing the Canvas app component property, it will “reserve” the proper screen real estate based on the underlying Canvas app display settings


Fig. 19. - Never mind about the error message which is only due to the preview in edit mode. Save and Publish


Fig. 20. - The blank Canvas App embedded and ready to be customized


Sample Canvas App for Segment Membership

Let’s now look again at “Brett Bear” who belongs to two segments:


Fig. 20. - Segments in CI-D


Fig. 21. - Segments in SegmentMembership table

Back to our Canvas App, what we want to do now is to fetch this list of segments from the SegmentMembership table and parse it into a collection (“MyTable” in the example below) so it can be displayed dynamically in a Gallery component.

Let’s first add the CustomerProfile and SegmentMembership table if they are not yet present.


Fig. 22. - Required tables

We can now edit the “OnDataRefresh” property of the “ModelDrivenFormIntegration” control to use the following formula:

Fig. 23. - "OnDataRefresh" property to access SegmentMembership from Contact through CustomerProfile and parse it into a collection ("MyTable") for later use

Decomposing the formula in Fig. 23. from the innermost indentation:
  • The backstamped CustomerId is retrieved from the Contact record passed as a context to the ModelDrivenFormIntegration control.
  • Then, this CustomerId is used to look up the corresponding SegmentMembership record, and its Segments column that contains the Json payload.
  • Finaly, the Json array of string Segments is parsed and accumulated in a collection variable named “MyTable”.
The next and last step is to create a simple Gallery:
  • Height and Width properties are set from the corresponding App properties to keep it responsive (i.e., “App.Height” and “App.Width”).
  • Items property is set to the “MyTable” collection.
  • TemplateSize property is set to “40
  • Selectable property is set to “False”.
We use a simple layout for the Gallery with only a Text label (and optionally a Separator):
  • Width property is set from the corresponding App property to keep it responsive (i.e., “App.Width”).
  • Text property is set to “ThisItem.Value”.
  • DisplayMode property is set to “DisplayMode.View”.
  • (Font) Size property is set to “10.5”.
Note that you will not see any data preview while editing the Canvas app, so you might have to publish it a few times, embedded in a test form for example, just to control the results once published.
Also note that once published, you might have to wait for up to a minute and refresh the form to see the results, as a visual help to confirm your latest modifications were indeed published and are what you get when refreshing the form, you can change the background color of your App every time you publish it.
​​​​​​​

Comments

*This post is locked for comments