Custom button in Dynamics 365: Trigger journeys with one click

What if we had a button in the ribbon bar that triggers  journeys in Dynamics 365? But how do you create a new button in the ribbon bar and how can it act as a trigger?

In my previous articles, I have already shown you how to use custom triggers in journeys. In most cases, the trigger triggered a Power Automate. Or, of course, we also have the Dataverse trigger, which fires when a record is created or a field is updated. These low-code/no-code variants are easy to implement, but today we want to go one step further. With a custom trigger and Javascript in Dynamics 365.

Whenever the button in the ribbon bar on the contact form is clicked, an email should be sent.

So, let’s get started and start creating the button.

Step 1: Create button in the command bar

To add a button to the command bar, go to your solution and add the contact table.

Create a new command and select “Main form” in the popup that appears, as we want to add the button to the contact form.

We can create the new button in the modern designer. Assign a label text and select an icon from the library. We will later enter the JavaScript from the trigger in the action area. First, you can add tooltip information and specify whether the button should be displayed or hidden. Use drag and drop to place the button in the desired position in the command bar.

Before we return here, let’s first create the trigger in Customer Insights.

Step 2: Create a trigger

I’m sure I don’t need to tell you in detail how to create a new trigger. So let’s keep it short. In the Customer Insights Journeys app, I create a custom trigger with the attribute and data type Contact. I don’t add any other attributes. Then I click on Next, Next and Ready to Use.

As soon as the trigger is created, you can click on Go to code snippet. Here you get the Javascript code and the code for the initial setup of the script. The initial code appears when you click on the One-time set up link.

We will add this script to a web resource later and then attach it to the button. But first we have to adapt the code.

Step 3: A bit of code magic

I prefer to use Visual Studio Code so that I can adapt and add to the code more easily. Otherwise it’s a mess. There I first insert the initial code and then the Javascript code from our trigger.

If we leave it like this now, the trigger would fire immediately after the button is clicked and send the email. That’s ok of course, but I find it a bit difficult. What if the user clicks on the button by mistake? Then the email can no longer be stopped.

That’s why we add a confirmation dialog for security. When the user clicks on the button, a dialog opens and the trigger is only activated when the user clicks on OK.

In the code, we also need to define for which contact the trigger should be started. We therefore add the primaryControl parameter. We need this to pass information about the execution context (form context or grid context) to the JavaScript function. This is because we can then receive the contactid variable. This is the GUID of the contact. And we have to put this after the authID in the trigger JavaScript. This is the only way for the journey to know which contact should receive the email.

Save the code as a file. The finished code looks like this:

				
					//initial code from the trigger:
(function (a, t, i) { const e = "MSEI"; const s = "Analytics"; const o = e + "queue"; a[o] = a[o] || []; const r = a[e] || function (n) { const t = {}; t[s] = {}; function e(e) { while (e.length) { const r = e.pop(); t[s][r] = function (e) { return function () { a[o].push([e, n, arguments]) } }(r) } } const r = "track"; const i = "set"; e([r + "Event", r + "View", r + "Action", i + "Property", i + "User", "initialize", "teardown"]); return t }(i.name); const n = i.name; if (!a[e]) { a[n] = r[s]; a[o].push(["new", n]); setTimeout(function () { const e = "script"; const r = t.createElement(e); r.async = 1; r.src = i.src; const n = t.getElementsByTagName(e)[0]; n.parentNode.insertBefore(r, n) }, 1) } else { a[n] = new r[s] } if (i.user) { a[n].setUser(i.user) } if (i.props) { for (const c in i.props) { a[n].setProperty(c, i.props[c]) } } a[n].initialize(i.cfg) })(window, document, {
    src: "https://download.pi.dynamics.com/sdk/web/msei-0.js",
    name: "msdynmkt",
    cfg: {
        ingestionKey:"cbe10dd607934e80bed9e498c1a1759d-1b54873a-1542-..."
    }
});

//the javascript of the trigger, add the primaryControl in the brackets:
function track_msdynmkt_copyofrequestconsent_140916360(primaryControl) {
    const confirmStrings = {
        //label and description of the confirmation dialog
        text: "By confirming this dialog an email will be send to this contact. Choose wisely.",
        title: "Are you sure?"
    };
    //design on the confirm options
    const confirmOptions = {
        height: 200,
        width: 450
    };
    //setting the variables for the primarycontrol and the contactid
    const formContext = primaryControl;    
    const contactid = formContext.data.entity.getId();
    //starting the confirmDialog
    Xrm.Navigation.openConfirmDialog(confirmStrings, confirmOptions).then(
        function (success) {    
            if (success.confirmed) {
                //when the use clicks on Ok the rest of the trigger code will be executed
                console.log("Dialog closed using OK button.");
                window["msdynmkt"].setUser({authId: contactid});   // ID, e-mail or phone number - see instructions
                window["msdynmkt"].trackEvent({
                    name: "msdynmkt_copyofrequestconsent_140916360", //Trigger title: Request Consent
                    ingestionKey : "cbe10dd607934e80bed9e498c1a1759d-1b54873a-",
                    version: "1.0.0" ,
                    properties: {
                 "bindingid" : "12345"
                }
                })
                //a notification is shown
                formContext.ui.setFormNotification("The email was sent. Congratulations!", "WARNING");
            } else {
               //nothing happens
            }
        }
    );
   }



				
			

Step 4: Create web resource

Now we create the web resource and insert our code there. To do this, go back to the PowerApps where we created the button. Because now we come to the action part. There you can choose between PowerFX and Javascript. Select “Javascript” in the action area.

In the library, you can use an existing script library and add your script from the previous chapter. Or you can create a new web resource. Give the web resource a suitable name, select Javascript as the type and upload your script file there.

Back in the PowerApps Designer, select your desired library. Then enter the function name in the field below. In our example, this is track_msdynmkt_copyofrequestconsent_140916360. You can find the name in the trigger javascript.

In the area below, add the PrimaryControl parameter. As already mentioned, we need this in the code to get the contact GUID.

Publish everything, of course, and then we come to the last step.

Step 5: Create journey

Now for the easiest part: create a trigger-based journey that starts with our trigger and then sends an email. Publish the journey.

A last test

Let’s take a look at the button in the contact form and test whether everything works.

Summary

In this article, we learned how to create a user-friendly button in the ribbon bar that triggers a journey in Dynamics 365 Customer Insights. From creating the button to customizing the Javascript code to the final publishing of the journey, we went through every step.

The possibilities with custom buttons are endless. In the future, for example, we could create buttons that trigger various automations, such as sending follow-up emails or launching more complex marketing campaigns. As always, there are no limits to the imagination!

***Please be aware: The content is accurate at the time of creation. It may be that Microsoft has made changes in the meantime.***

Check out the FAQ section of my blog as well: Short questions with quick answers! Go to FAQs

One Response

  1. It took me forever to realise I selected PrimaryControllId instead of PrimaryControl, but beside that it works like a charm haha! Thanks for sharing!

Leave a Reply

Your email address will not be published. Required fields are marked *

WordPress Cookie Notice by Real Cookie Banner