Skip to main content

Sitecore 9 - Creating Custom Marketing Automation Activity Part-2

I am going to build user interface part of custom activity. As we saw in previous post, we have a parameter called "ProcessLimit" in activity implementation. So, we should provide a UI to marketing managers that can set it from marketing automation panel.

I don't want to repeat the official documentation, I will only show some key parts.

I started with creating package.json file. When you follow official documentation, you see that you need those packages as required.

  • @angular/core: 5.2.11
  • @angular/http: 5.2.11
  • @ngx-translate/core: 9.0.2
  • rxjs: 5.5.11
You will get warning in terminal if there is any package missing, I added step by step and my final package.json file was like this:

{
  "name": "package",
  "version": "1.0.0",
  "description": "Playground Demo",
  "private": true,
  "angular-cli": {},
  "scripts": {
    "dev": "ngc -p ./src/tsconfig.aot.json && npm run build",
    "build": "webpack --display-error-details"
  },
  "dependencies": {
    "@angular/common": "5.2.11",
    "@angular/compiler": "7.2.4",
    "@angular/compiler-cli": "^7.2.4",
    "@angular/core": "5.2.11",
    "@angular/forms": "5.2.11",
    "@angular/http": "5.2.11",
    "@angular/platform-browser": "5.2.11",
    "@ngx-translate/core": "^9.0.2",
    "@sitecore/ma-core": "file:C:/Playground/Playground.Angular/MarketingAutomation/packages/ma-core",
    "rxjs": "^5.5.11",
    "typescript": "3.2.4",
    "zone.js": "^0.8.4"
  },
  "devDependencies": {
    "ts-loader": "^5.3.3",
    "webpack": "^4.29.3",
    "webpack-cli": "^3.2.3"
  },
  "main": "index.js",
  "author": "",
  "license": "ISC"
}

An important dependency is "@sitecore/ma-core". Sitecore provides a package to use as base and build our UI. We need to give the ma-core path which inside MarketingAutomation folder.

The folder structure is below, you can see an overview what kind of files you will have at the end.


Another important thing is id in plugin.ts file. The Sitecore id of created activity type must be lower case and without curly brackets.

import { Plugin } from '@sitecore/ma-core';
import { SendMoviesToExpressActivity }  from './send-movies-to-express.activity';
import { EditorComponent } from '../codegen/editor/editor.component';
import { SendMoviesToExpressModuleNgFactory } from '../codegen/send-movies-to-express-module.ngfactory'

@Plugin({
    activityDefinitions: [ 
        {
            // The ID must match the ID of the activity type description definition item in the CMS.
            // Must be lowercase and without curly brackets
        id: 'c61c5489-b11b-40f1-ab36-23eb044c2e69',
            activity: SendMoviesToExpressActivity,
            editorComponenet: EditorComponent,
            editorModuleFactory: SendMoviesToExpressModuleNgFactory
        }
    ]
})
export default class SendMoviesToExpressPlugin {}

You will see the activity component implementation below. Remember that we defined parameter name as ProcessLimit in code. Here, it must start with lowercase "processLimit".

import { SingleItem } from '@sitecore/ma-core';

export class SendMoviesToExpressActivity extends SingleItem {

    getVisual(): string {
        const subTitle = this.isDefined ? 'Process Count: ' + this.editorParams.processLimit : '';
        const cssClass = this.isDefined ? '' : 'undefined';

        //CSS class can either be makreting-action or other-element
        return `
            <div class="viewport-readonly-editor marketing-action ${cssClass}">
                <span class="icon">
                    <img src="/~/icon/OfficeWhite/32x32/arrow_right.png" />
                </span>
                <p class="text with-subtitle" title="Send movies">
                    Send movies
                    <small class="subtitle" title="${subTitle}">${subTitle}</small>
                </p>
            </div>
        `;
    }

    get isDefined(): boolean {
        /*
        The editorParams propery value is the object that is serialized from the activity editor.
        If the activity is undefined the editorParams propery will evaluate to {}
        */
        return Boolean(this.editorParams.processLimit);
    }
}

Editor component has an input field to set our parameter.

import { Component, OnInit, Injector } from '@angular/core';
import { EditorBase } from '@sitecore/ma-core';
 
@Component({
    selector: 'readonly-editor',
            template: `
        <section class="content">
            <div class="form-group">
                <div class="row readonly-editor">
                    <label class="col-6 title">Process Limit</label>
                    <div class="col-6">
                        <input type="number" class="form-control" [(ngModel)]="processLimit"/>
                   </div>
                </div>
            </div>
        </section>
    `,
    //CSS Styles are ommitted for brevity
    styles: ['']
})
 
export class EditorComponent extends EditorBase implements OnInit {

    processLimit: number;

    constructor(private injector: Injector) {
        super();
    }
 
    ngOnInit(): void { 
        this.processLimit = this.model ? this.model.processLimit || 0 : 0;
    }

    serialize(): any {
        return {  
            processLimit: this.processLimit
        };
    }
}

Once you are done with components. you can build your app with "npm run dev" command. If there is no error, you will get an bundled js file which include all necessary things.

There are two things left to make it work at this moment. First, I copied this js file and pasted under plugins folder (C:\inetpub\wwwroot\yourwebsite\sitecore\shell\client\Applications\MarketingAutomation\plugins). Then, added a configuration file under App_Config/Include folder to register js file.

<?xml version="1.0" encoding="utf-8" ?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:set="http://www.sitecore.net/xmlconfig/set/" xmlns:role="http://www.sitecore.net/xmlconfig/role/">
  <sitecore role:require="Standalone or ContentManagement or DedicatedDispatch">
    <marketingAutomation>
    <pluginDescriptorsRepository>
      <plugins>
        <!-- Assuming that the plugin bundle file name is sample.plugin.js and is deployed directly under the plugins folder -->
        <plugin path="./plugins/send-movies.plugin.js" />
      </plugins>
    </pluginDescriptorsRepository>
    </marketingAutomation>
  </sitecore>
</configuration>

At the end my custom action looked like this:


That's it! You can test and you can debug your code as I showed in previous posts. 

Comments

Popular posts from this blog

Deploying SolrCloud with Zookeeper on Azure Kubernetes Service (AKS)

SolrCloud on Azure Kubernetes Service (AKS) Running SolrCloud on Kubernetes — particularly Azure Kubernetes Service (AKS) — can provide you with a highly scalable, cost-efficient, and cloud-native architecture.  This guide walks through how I deployed SolrCloud 8.11.2 with Zookeeper on AKS . Why This Matters for Sitecore Deployments If you're running Sitecore XP or XM , you know that Solr is a mandatory dependency — powering xDB indexing, content search. While Sitecore provides a developer-friendly Solr container for local use, it clearly states: ⚠️ The included Solr image is intended only for development and testing . This means Sitecore does not provide a production-ready Solr setup. If you're deploying Sitecore in production — especially in Kubernetes — you need to create your own scalable, HA SolrCloud cluster. That’s why this deployment matters: You’re building a production-grade SolrCloud setup You’re deploying 3 Solr + 3 Zookeeper nodes for high availabilit...

Sitecore Commerce – XC9 Tips – Missing Commerce Components in SXA Toolbox on Experience Editor

I've recently had an issue that commerce components were missing in SXA Toolbox. I setup Sitecore Commerce on top of an existing instance and I already had a SXA website working on it. The idea was to add commerce components and functionality to my existing website. But after commerce setup, the toolbox was still showing default SXA components and commerce components were missing although I add commerce tenant and website modules: I checked Available Renderings under Presentation folder, there was no problem, commerce renderings were there. I created another tenant and website to see if it shows the commerce components in toolbox. Nothing seemed different but I was seeing commerce components for new website and it was missing on existing one. Then, I noticed two things: 1- Selected catalog was empty in content editor (/sitecore/Commerce/Catalog Management/Catalogs) even if I see Habitat_Master catalog in Merchandising section on commerce management panel. 2- Bootstrap ...

Modern Observability for Sitecore 10.4 on AKS: Grafana, Alloy, Loki, and Prometheus

In this post, I’ll walk through how I extended the base Sitecore XM 10.4 AKS setup with a modern observability stack using Grafana, Alloy, Loki, and Prometheus. This setup provides deep insights into both infrastructure and application health, with powerful log aggregation and visualization. Project Overview Base:  Sitecore XM 10.4 running on Azure Kubernetes Service (AKS) Enhancements:  Added a full Grafana observability stack: Grafana  for dashboards and visualization Alloy  (Grafana Alloy, formerly Promtail) for log collection and multiline parsing Loki  for log aggregation and querying Prometheus  for metrics collection All configuration...