Call Vlocity Integration Procedures from Lightning Web Components

Ever wondered that it would be pretty interesting if we were able to call that well contained but complex integration procedure reused in x other OmniScripts into a Lightning Web Component(LWC). 

Imagine the declarative nature  of the Integration procedure – no apex, no AuraEnabled decorated methods, no test classes - with the flexibility of the LWC would make prototyping blazing fast. 

Since Winter ’20 release Vlocity introduced the new LWC OmniScript Action Framework that allows to make remote calls using the framework methods by simply importing the Common Action Utility class.

Let’s see how we can leverage the LWC OmniScript Action Framework to integrate an external service to shorten URLs through an Integration Procedure(IP) into a standalone LWC embedded in an Omniscript(OS).  

Take note that the same result could be achieved with a IP directly called in a OS Step with two input fields to hold the URLs, the POC that we’ll build just proves the point and you can use it on more complex flows whereby you need to call IPs in LWC, for instance when overriding OS components.

Lightning Web Component

Our first step is to create the custom LWC that will be responsible for accepting the URL inputted by the user, call the IP, receive and display the response.

1. The .js-meta.xml configuration

  • To expose the component to the app builder the <isExposed> element must be set to true.

  • The namespace of the Vlocity package must also be set in the  <runtimeNamespace> metadata element. 

You can quickly check the namespace of the Vlocity package you’re running in the Installed Packages on Salesforce Setup. In this example I’ll use the vlocity_cmt - the namespace for the Vlocity Communications, Media and Energy managed package.

The xml file should look like this:


<?xml version="1.0" encoding="UTF-8"?>

<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">

    <apiVersion>50.0</apiVersion>

    <isExposed>true</isExposed>

    <runtimeNamespace>vlocity_cmt</runtimeNamespace>

</LightningComponentBundle>

2. The .html file

  • For the html we’ll create a container using the <lightning-card > that will group two input fields <lightning-input> of the type url, so we can have a nice out of the box URL validation. The input field with the iurl class will receive the user input and the field with the ourl class will output the url from the IP through the shortURL reactive property:

<template>

    <lightning-card title="URL Shortener" icon-name="standard:link">

        <lightning-input class="iurl" type="url" name="inputURL" placeholder="Enter valid URL here..."></lightning-input>

        <lightning-input class="ourl" type="url" name="outputURL" value={shortURL}></lightning-input>

    </lightning-card>

</template>

  • Next to the input fields two buttons, pressing on the <lightning-button> will allow to shorten the URL using the JavaScript method handleShortenURL and copy the shortened URL to the clipboard via handleCopy method:

<template>

    <lightning-card title="URL Shortener" icon-name="standard:link">

        <lightning-input class="iurl" type="url" name="inputURL" placeholder="Enter valid URL here..."></lightning-input>

        <lightning-button variant="brand" label="Shorten" onclick={handleShortenURL}></lightning-button>

        <lightning-input class="ourl" type="url" name="outputURL" value={shortURL}></lightning-input>

        <lightning-button icon-name="utility:copy_to_clipboard" variant="brand" label="Copy" onclick={handleCopy}></lightning-button>

    </lightning-card>

</template>

  • Since the field that holds the shortened URL will be necessary only after the user triggered the action we will add a conditional rendering <div if:true={isSuccess}… so it only displays on a successful shortening of the URL .

After arranging and adding some styling the final html look like this:

<template>

    <lightning-card title="URL Shortener" icon-name="standard:link">

        <div class="slds-grid slds-grid_vertical-align-end slds-gutters">

            <div class="slds-col slds-size_2-of-3">

                <lightning-input class="iurl" type="url" name="inputURL" placeholder="Enter valid URL here..."></lightning-input>

            </div>

            <div class="slds-col slds-size_1-of-3">

                <lightning-button variant="brand" label="Shorten" onclick={handleShortenURL}></lightning-button>

            </div>

        </div>

        <div if:true={isSuccess} class="slds-grid slds-grid_vertical-align-end slds-gutters slds-p-top_medium">

            <div class="slds-col slds-size_2-of-3">

                <lightning-input class="ourl" type="url" name="outputURL" value={shortURL}></lightning-input>

            </div>

            <div class="slds-col slds-size_1-of-3">

                <lightning-button icon-name="utility:copy_to_clipboard" variant="brand" label="Copy" onclick={handleCopy}></lightning-button>

            </div>

        </div>

    </lightning-card>

</template>

3. The javascript file

To take advantage of the  Vlocity LWC OmniScript Action Framework we will have to import the Vlocity OmniscriptActionCommonUtil utility class from the Vlocity omniscriptActionUtils. This class will give us access to the executeAction method where, in the parameters, we can define the Integration Procedure that will be called, the input to send, and which options to switch on, such as run as future, queueable and chainable. The executeAction will start the call to the IP and return a promise with a result property that contains the response from the IP and an Boolean error property that indicates the status of the invocation. From the result property we get the URL shortened and an Boolean indicative of the successful http action call and assign them  to the reactive fields shortURL and isSuccess that upon update will re-render in the html template surfacing the shortened URL and the copy button in the UI.

  • Let’s first import the OmniscriptActionCommonUtil and instantiate it on the connectedCallback()  so we have the methods available whenever we request them.

We will also use the imported getNamespaceDotNotation() from the omniscriptInternalUtils so we can retrieve the Vlocity Package namespace:

import { LightningElement } from "lwc";

import { getNamespaceDotNotation } from "vlocity_cmt/omniscriptInternalUtils";

import { OmniscriptActionCommonUtil } from "vlocity_cmt/omniscriptActionUtils";

 

export default class UrlShortener extends LightningElement {

    _actionUtil;

    _ns = getNamespaceDotNotation();

 

    connectedCallback() {

        this._actionUtil = new OmniscriptActionCommonUtil();

    }

}

  • Now that we have all the utilities we need from the Vlocity package we can start to give body to the handleShortenURL() function. Here we will make use of the executeAction that we call from the  action common utils that we just instantiated. Using the template.querySelector(".iurl") we can reach the lightning element holding the URL that the user has typed, we pass it as value for the input key of the executeAction parameter; for the sClassName key we must use the IntegrationProcedureService prefixed by the namespace;  for the sMethodName we will have to write the Integration Procedure in the format of type_Subtype, for our example let’s call the Subtype “URLShortenerIntegration” and “integration” for the type.Since we are not using  any option (eg. chainable) we will leave the option object empty:

import { LightningElement } from "lwc";

import { getNamespaceDotNotation } from "vlocity_cmt/omniscriptInternalUtils";

import { OmniscriptActionCommonUtil } from "vlocity_cmt/omniscriptActionUtils";

 

export default class UrlShortener extends LightningElement {

    _actionUtil;

    _ns = getNamespaceDotNotation();

 

    connectedCallback() {

        this._actionUtil = new OmniscriptActionCommonUtil();

    }

 

    handleShortenURL() {

        let input = this.template.querySelector(".iurl").value;

 

        this.IPInput = {

            url: input

        };

 

        const options = {};

        const params = {

            input: JSON.stringify(this.IPInput),

            sClassName: `${this._ns}IntegrationProcedureService`,

            sMethodName: "integration_URLShortenerIntegration",

            options: JSON.stringify(options)

        };

    }

}

  • Finally we can call the executeAction and pass the parameters we set before. After it's executed it will return a promise with the response from the IP, when done it’s the time to update our fields isSuccess and shortURL so that the data displays on the screen.

Note that executeAction receives 5 arguments being, the parameters as an object, a string with the queueable Id, the component, an extra payload and some other vlocity params, in most cases the parameters and the component are sufficient and we can safely nullify all other arguments:

import { LightningElement } from "lwc";

import { getNamespaceDotNotation } from "vlocity_cmt/omniscriptInternalUtils";

import { OmniscriptActionCommonUtil } from "vlocity_cmt/omniscriptActionUtils";

 

export default class UrlShortener extends LightningElement {

    shortURL;

    isSuccess;

    _actionUtil;

    _ns = getNamespaceDotNotation();

    

    /* ... */

    

    handleShortenURL() {

        

        /* ... */

        

        this._actionUtil

            .executeAction(paramsnullthisnullnull)

            .then((response) => {

                this.shortURL = response.result.IPResult.response;

                this.isSuccess = response.result.IPResult.isSuccess;

            })

            .catch((error) => {

                console.error(error"ERROR");

            });

    }

}

  • As a bonus I’ve added a copy button so the user can quickly copy the shortened link to the clipboard.

 The handleCopy() will create a short lived document that will hold the link string. Using the execCommand("copy")  we will execute the copy command so the selected input element of the document is copied to the clipboard:

import { LightningElement } from "lwc";

import { getNamespaceDotNotation } from "vlocity_cmt/omniscriptInternalUtils";

import { OmniscriptActionCommonUtil } from "vlocity_cmt/omniscriptActionUtils";

 

export default class UrlShortener extends LightningElement {

    

    /* ... */

 

    handleCopy() {

        var tempInput = document.createElement("input");

        tempInput.setAttribute("value"this.shortURL);

        document.body.appendChild(tempInput);

        tempInput.select();

        document.execCommand("copy");

        document.body.removeChild(tempInput);

    }

}

Our final version of the javascript file will look like this:

import { LightningElement } from "lwc";

import { getNamespaceDotNotation } from "vlocity_cmt/omniscriptInternalUtils";

import { OmniscriptActionCommonUtil } from "vlocity_cmt/omniscriptActionUtils";

 

export default class UrlShortener extends LightningElement {

    shortURL;

    isSuccess;

    _actionUtil;

    _ns = getNamespaceDotNotation();

 

    connectedCallback() {

        this._actionUtil = new OmniscriptActionCommonUtil();

    }

 

    handleShortenURL() {

        let input = this.template.querySelector(".iurl").value;

 

        this.IPInput = {

            url: input

        };

 

        const options = {};

        const params = {

            input: JSON.stringify(this.IPInput),

            sClassName: `${this._ns}IntegrationProcedureService`,

            sMethodName: "integration_URLShortenerIntegration",

            options: JSON.stringify(options)

        };

        this._actionUtil

            .executeAction(paramsnullthisnullnull)

            .then((response) => {

                this.shortURL = response.result.IPResult.response;

                this.isSuccess = response.result.IPResult.isSuccess;

            })

            .catch((error) => {

                console.error(error"ERROR");

            });

    }

 

    handleCopy() {

        var tempInput = document.createElement("input");

        tempInput.setAttribute("value"this.shortURL);

        document.body.appendChild(tempInput);

        tempInput.select();

        document.execCommand("copy");

        document.body.removeChild(tempInput);

    }

}

Integration Procedure

We will delegate the process to shorten the URLs to the cleanuri.com API services that we’ll access through an HTTP call action. Besides returning the shortened URL, the response from cleanuri.com will be screened for errors and a isSuccess Boolean node returned to allow conditionally render the URL and the copy button on the LWC UI.

  • The type and subtype of the IP have to match the same we’ve set on the sMethodName in the javascript file:

 

 

 

  • Following the documentation from cleanuri.com/docs we can set up a simple HTTP Action that receives the url parameter from the LWC to the merge field which will be sent to the cleanuri.com services for processing: 

 

  • To the response node we assign the result from the call and if there was any error captured we will compute it as a Boolean to the parameter isSuccess:

 

Omniscript

Finally we will wrap our LWC inside an Omniscript through a standalone Custom LWC. This way we can leverage the Vlocity packages and utils we saw until now.

  • The Omniscript was configured to be LWC enabled and without Step Chart. Since we are not interacting with the Omniscript data we can mark the Custom LWC as standalone:

 

Flexipage

We are left only with the configuration of the display of the LWC Omniscript on a record flexipage.

 

A reprodução deste vídeo não está disponível neste momento

0:17

And now the final result. And the mini POC is live!

Conclusion

Although being a simple component we built, we can see the benefits of using the OmniScript Action Framework to make remote calls to Integration Procedures leveraging its declarative programming for fast implementation of backend processes coupled with LWC to build flexible web components tailored to meet customers UI/UX expectations.

Os campos obrigatórios estão assinalados com um asterisco(*)

Ao submeter este formulário assume ter lido a nossa declaração de privacidade, dando o seu consentimento para que façamos o processamento de dados de acordo com a referida declaração (incluindo transferências internacionais). Se, a qualquer momento, mudar de ideias quanto à receção de informação sobre a PwC, poderá enviar-nos um email.

Contacte-nos

Luís Côrte-Real

Luís Côrte-Real

Customer Transformation Director, PwC Portugal

Fechar