You need to sign in to do that
Don't have an account?
Afzaal Hassan
Formatting the JS in a Five9 IVR LWC component
Hello
I am integrating Five9 IVR system into my SF org. Five9 gave me a sample code that is basically an LWC component so that an agen can enter the amount and order number. When I am putting that LWC in a Contact record (in the app builder), its showig up fine. But I actually want to put it in a Case record. When I put it there, the component just shows the title and not the fields. This is probably because the JS file is referencing the contact object. I dont know how to modify this JS so that it shows up in the case record. Also, i have a ContactId in my case object as a field. Here is the JS and HTML file. Thanks
Meta XML file:
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata" fqn="five9SecurePayment">
<apiVersion>45.0</apiVersion>
<isExposed>true</isExposed>
<targets>
<!-- <target>lightning__HomePage</target> -->
<!-- <target>lightning__AppPage</target> -->
<target>lightning__RecordPage</target>
</targets>
<targetConfigs>
<targetConfig targets="lightning__RecordPage">
<objects>
<object>Case</object> //changed this to Case from contact
</objects>
</targetConfig>
</targetConfigs>
</LightningComponentBundle>
HTML file:
<template>
<lightning-card title="Five9 Secure Payment 2.0" icon-name="custom:custom17">
<template if:true={contact.data}>
<div class="slds-m-around_medium">
<!-- <p>{contactName} - <lightning-formatted-phone value={contactPhone}></lightning-formatted-phone></p> -->
<lightning-input type="number" name="paymentAmount" required label="Transaction Amount" value="12.34" placeholder="Enter the amount of the transaction" formatter="currency" step="0.01"></lightning-input>
<lightning-input pattern="[0-9]{5}" name="invoiceNumber" label="Invoice Number" value="12345" placeholder="Enter the 5 digit invoice number"></lightning-input>
<br>
<lightning-button label="Start with Events" variant="brand" title="Start with Events" onclick={startSecurePaymentWithEvents} class="slds-m-left_x-small"></lightning-button>
<lightning-button label="Start" variant="brand" title="Start" onclick={startSecurePayment} class="slds-m-left_x-small"></lightning-button>
<lightning-button label="Cancel" variant="destructive" title="Cancel" onclick={cancelSecurePayment} class="slds-m-left_x-small"></lightning-button>
</div>
</template>
<!-- <template if:true={contact.error}>
<c-error-panel errors={contact.error}></c-error-panel>
</template> -->
</lightning-card>
</template>
JS file:
/* eslint-disable no-console */
import { LightningElement, api, wire } from 'lwc';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
import { getRecord } from 'lightning/uiRecordApi';
import * as secpay from './five9secpay';
import { Five9BridgeClient } from './five9bridgeclient';
// These are the Contact Fields that we get and send as cavs
const FIELDS = [
'Contact.FirstName',
'Contact.LastName'
]; // these fields need to change to have case fields i think
// CAV to pass the client's unique Bridge REST request URL.
// NOTE that the IVR must reference the same CAV name.
// Also, any campaigns must add this and any application specific CAVs to their Campaign Profile's Layout in the Five9 Admin
const cavBridgeURL = "SecurePay.BridgeURL";
let callVariables;
let self;
export default class SecurePayment extends LightningElement {
five9bridgeclient = new Five9BridgeClient();
@api objectApiName; // Set by Lightning to the name of the object type
@api recordId; // Set by Lightning to the ID of the object
// This uses this page's recordID to retrieve the contact's first and last name
@wire(getRecord, { recordId: '$recordId', fields: FIELDS }) contact; //should this case instead of contact?
get contactFirstName() {
return this.contact.data.fields.FirstName.value;
}
get contactLastName() {
return this.contact.data.fields.LastName.value;
}//above 2 methd probably need to be modified
get paymentAmount() {
const inputs = this.template.querySelectorAll('lightning-input');
for (let i = 0; i < inputs.length; i++) {
if (inputs[i].name === 'paymentAmount') {
return inputs[i].value;
}
}
return undefined;
}
get invoiceNumber() {
const inputs = this.template.querySelectorAll('lightning-input');
for (let i = 0; i < inputs.length; i++) {
if (inputs[i].name === 'invoiceNumber') {
return inputs[i].value;
}
}
return undefined;
}
// Our constructor wires in the secpay's callback for the result event
constructor() {
super();
self = this;
secpay.initialize(this._onSecurePaymentStarted);
}
_onOpenEvent(bridgeURL) {
// OK, if we get our URL then we be rolling!
// Lets see if we can send a message to ourselves...
console.log(`WebSocket Opened, Session URL: ${bridgeURL}, initiate secure payment IVR connection`);
// Add the Bridge Server's URL as a CAV.
// The script will use this to send real time messages and any other desired information back to this client
// by POSTing JSON formatted messages to this URL. This URL uniquely identifies this client's session.
callVariables.push({name: cavBridgeURL, value: bridgeURL});
// Now start the secure payment
secpay.startSecurePayment(callVariables);
}
_onDataEvent(jsonData) {
let eventData = JSON.parse(jsonData);
// Is this a message?
if (eventData.type === "message") {
// Yes, show the status
let message = eventData.message;
const evt = new ShowToastEvent({
title: "Payment Status",
message: message,
variant: 'info'
});
dispatchEvent(evt);
}
// Is this a result?
else if (eventData.type === 'result') {
// Yes, show the result
let success = eventData.success;
let message = eventData.message;
const evt = new ShowToastEvent({
title: "Payment Result",
message: message,
variant: success ? 'success' : "error",
url: "www.five9.com"
});
dispatchEvent(evt);
}
}
_onCloseEvent(error) {
if (error) {
const evt = new ShowToastEvent({
title: "Bridge Event Connection Closed Due to Error",
message: error.message,
variant: "error"
});
dispatchEvent(evt);
}
console.log("WebSocket closed");
}
// Method used to initiate the secure payment
_initiateSecurePayment(withEvents) {
// eslint-disable-next-line no-debugger
debugger;
// Make sure our data is OK
if (!this.paymentAmount || !this.invoiceNumber) {
const evt = new ShowToastEvent({
title: "Secure Payment",
message: 'Amount and Invoice fields must both be set',
variant: 'warning'
});
dispatchEvent(evt);
return;
}
//*** Set the CAVs here ***
callVariables = [
{name: 'SecurePay.FirstName', value: this.contactFirstName}, // This comes from the SF Contact
{name: 'SecurePay.LastName', value: this.contactLastName}, // This comes from the SF Contact. These 2 lines need to be changed
{name: 'SecurePay.InvoiceNumber', value: this.invoiceNumber}, // This comes from the LWC form
{name: 'SecurePay.PaymentAmount', value: this.paymentAmount} // This comes from the LWC form
];
// Are we using the Five9 Bridge Service to get events?
if (withEvents) {
// We don't know when to close our socket IF we made a sec payment request as we don't get an event when it completes.
// So, we always check for and close here if needed. Right now we don't provide any feedback as this would only
// happen if the script didn't send a DELETE at the end of a previous secure payment IVR session which is a defect.
if (this.five9bridgeclient.isOpen()) {
this.five9bridgeclient.close();
return;
}
// Now kick things off by opening the bridge client. The callbacks will drive us forward and once the socket is open and connected
// we'll go ahead and start the secure payment call process.
try {
// Parms: wsURL, dataEvent, urlEvent, closeEvent
// this.five9bridgeclient.open(this._onDataEvent, this._onOpenEvent, this._onCloseEvent, "ws://localhost:5555/bridge");
this.five9bridgeclient.open(this._onDataEvent, this._onOpenEvent, this._onCloseEvent);
} catch (ex) {
const evt = new ShowToastEvent({
title: "Secure Payment",
message: `Failed trying to open connection to event Server: ${ex.message}`,
variant: 'error'
});
dispatchEvent(evt);
}
} else {
secpay.startSecurePayment(callVariables);
}
}
_onSecurePaymentStarted(message, error) {
// Did we get an error?
if (error) {
// If we failed to start the sec pay conference then we need to close the
// Bridge Web Socket if we have a session open
if (self.five9bridgeclient.isOpen()) {
self.five9bridgeclient.close();
}
}
const evt = new ShowToastEvent({
title: (error ? "Failure" : "Success"),
message: message,
variant: (error ? 'error' : 'success'),
});
dispatchEvent(evt);
}
// Method used to initiate the secure payment
startSecurePayment() {
this._initiateSecurePayment(false);
}
// Method used to initiate the secure payment with events
startSecurePaymentWithEvents() {
this._initiateSecurePayment(true);
}
// Method used to cancel an active secure pay IVR session
cancelSecurePayment() {
if (this.five9bridgeclient.isOpen()) {
this.five9bridgeclient.close();
}
secpay.cancelSecurePayment(true);
}
}
There were other JS files in this sample that five9 provided and I can provide that if needed. Please someone help me modify this JS because I cant get his to work on Case. Thanks
I am integrating Five9 IVR system into my SF org. Five9 gave me a sample code that is basically an LWC component so that an agen can enter the amount and order number. When I am putting that LWC in a Contact record (in the app builder), its showig up fine. But I actually want to put it in a Case record. When I put it there, the component just shows the title and not the fields. This is probably because the JS file is referencing the contact object. I dont know how to modify this JS so that it shows up in the case record. Also, i have a ContactId in my case object as a field. Here is the JS and HTML file. Thanks
Meta XML file:
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata" fqn="five9SecurePayment">
<apiVersion>45.0</apiVersion>
<isExposed>true</isExposed>
<targets>
<!-- <target>lightning__HomePage</target> -->
<!-- <target>lightning__AppPage</target> -->
<target>lightning__RecordPage</target>
</targets>
<targetConfigs>
<targetConfig targets="lightning__RecordPage">
<objects>
<object>Case</object> //changed this to Case from contact
</objects>
</targetConfig>
</targetConfigs>
</LightningComponentBundle>
HTML file:
<template>
<lightning-card title="Five9 Secure Payment 2.0" icon-name="custom:custom17">
<template if:true={contact.data}>
<div class="slds-m-around_medium">
<!-- <p>{contactName} - <lightning-formatted-phone value={contactPhone}></lightning-formatted-phone></p> -->
<lightning-input type="number" name="paymentAmount" required label="Transaction Amount" value="12.34" placeholder="Enter the amount of the transaction" formatter="currency" step="0.01"></lightning-input>
<lightning-input pattern="[0-9]{5}" name="invoiceNumber" label="Invoice Number" value="12345" placeholder="Enter the 5 digit invoice number"></lightning-input>
<br>
<lightning-button label="Start with Events" variant="brand" title="Start with Events" onclick={startSecurePaymentWithEvents} class="slds-m-left_x-small"></lightning-button>
<lightning-button label="Start" variant="brand" title="Start" onclick={startSecurePayment} class="slds-m-left_x-small"></lightning-button>
<lightning-button label="Cancel" variant="destructive" title="Cancel" onclick={cancelSecurePayment} class="slds-m-left_x-small"></lightning-button>
</div>
</template>
<!-- <template if:true={contact.error}>
<c-error-panel errors={contact.error}></c-error-panel>
</template> -->
</lightning-card>
</template>
JS file:
/* eslint-disable no-console */
import { LightningElement, api, wire } from 'lwc';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
import { getRecord } from 'lightning/uiRecordApi';
import * as secpay from './five9secpay';
import { Five9BridgeClient } from './five9bridgeclient';
// These are the Contact Fields that we get and send as cavs
const FIELDS = [
'Contact.FirstName',
'Contact.LastName'
]; // these fields need to change to have case fields i think
// CAV to pass the client's unique Bridge REST request URL.
// NOTE that the IVR must reference the same CAV name.
// Also, any campaigns must add this and any application specific CAVs to their Campaign Profile's Layout in the Five9 Admin
const cavBridgeURL = "SecurePay.BridgeURL";
let callVariables;
let self;
export default class SecurePayment extends LightningElement {
five9bridgeclient = new Five9BridgeClient();
@api objectApiName; // Set by Lightning to the name of the object type
@api recordId; // Set by Lightning to the ID of the object
// This uses this page's recordID to retrieve the contact's first and last name
@wire(getRecord, { recordId: '$recordId', fields: FIELDS }) contact; //should this case instead of contact?
get contactFirstName() {
return this.contact.data.fields.FirstName.value;
}
get contactLastName() {
return this.contact.data.fields.LastName.value;
}//above 2 methd probably need to be modified
get paymentAmount() {
const inputs = this.template.querySelectorAll('lightning-input');
for (let i = 0; i < inputs.length; i++) {
if (inputs[i].name === 'paymentAmount') {
return inputs[i].value;
}
}
return undefined;
}
get invoiceNumber() {
const inputs = this.template.querySelectorAll('lightning-input');
for (let i = 0; i < inputs.length; i++) {
if (inputs[i].name === 'invoiceNumber') {
return inputs[i].value;
}
}
return undefined;
}
// Our constructor wires in the secpay's callback for the result event
constructor() {
super();
self = this;
secpay.initialize(this._onSecurePaymentStarted);
}
_onOpenEvent(bridgeURL) {
// OK, if we get our URL then we be rolling!
// Lets see if we can send a message to ourselves...
console.log(`WebSocket Opened, Session URL: ${bridgeURL}, initiate secure payment IVR connection`);
// Add the Bridge Server's URL as a CAV.
// The script will use this to send real time messages and any other desired information back to this client
// by POSTing JSON formatted messages to this URL. This URL uniquely identifies this client's session.
callVariables.push({name: cavBridgeURL, value: bridgeURL});
// Now start the secure payment
secpay.startSecurePayment(callVariables);
}
_onDataEvent(jsonData) {
let eventData = JSON.parse(jsonData);
// Is this a message?
if (eventData.type === "message") {
// Yes, show the status
let message = eventData.message;
const evt = new ShowToastEvent({
title: "Payment Status",
message: message,
variant: 'info'
});
dispatchEvent(evt);
}
// Is this a result?
else if (eventData.type === 'result') {
// Yes, show the result
let success = eventData.success;
let message = eventData.message;
const evt = new ShowToastEvent({
title: "Payment Result",
message: message,
variant: success ? 'success' : "error",
url: "www.five9.com"
});
dispatchEvent(evt);
}
}
_onCloseEvent(error) {
if (error) {
const evt = new ShowToastEvent({
title: "Bridge Event Connection Closed Due to Error",
message: error.message,
variant: "error"
});
dispatchEvent(evt);
}
console.log("WebSocket closed");
}
// Method used to initiate the secure payment
_initiateSecurePayment(withEvents) {
// eslint-disable-next-line no-debugger
debugger;
// Make sure our data is OK
if (!this.paymentAmount || !this.invoiceNumber) {
const evt = new ShowToastEvent({
title: "Secure Payment",
message: 'Amount and Invoice fields must both be set',
variant: 'warning'
});
dispatchEvent(evt);
return;
}
//*** Set the CAVs here ***
callVariables = [
{name: 'SecurePay.FirstName', value: this.contactFirstName}, // This comes from the SF Contact
{name: 'SecurePay.LastName', value: this.contactLastName}, // This comes from the SF Contact. These 2 lines need to be changed
{name: 'SecurePay.InvoiceNumber', value: this.invoiceNumber}, // This comes from the LWC form
{name: 'SecurePay.PaymentAmount', value: this.paymentAmount} // This comes from the LWC form
];
// Are we using the Five9 Bridge Service to get events?
if (withEvents) {
// We don't know when to close our socket IF we made a sec payment request as we don't get an event when it completes.
// So, we always check for and close here if needed. Right now we don't provide any feedback as this would only
// happen if the script didn't send a DELETE at the end of a previous secure payment IVR session which is a defect.
if (this.five9bridgeclient.isOpen()) {
this.five9bridgeclient.close();
return;
}
// Now kick things off by opening the bridge client. The callbacks will drive us forward and once the socket is open and connected
// we'll go ahead and start the secure payment call process.
try {
// Parms: wsURL, dataEvent, urlEvent, closeEvent
// this.five9bridgeclient.open(this._onDataEvent, this._onOpenEvent, this._onCloseEvent, "ws://localhost:5555/bridge");
this.five9bridgeclient.open(this._onDataEvent, this._onOpenEvent, this._onCloseEvent);
} catch (ex) {
const evt = new ShowToastEvent({
title: "Secure Payment",
message: `Failed trying to open connection to event Server: ${ex.message}`,
variant: 'error'
});
dispatchEvent(evt);
}
} else {
secpay.startSecurePayment(callVariables);
}
}
_onSecurePaymentStarted(message, error) {
// Did we get an error?
if (error) {
// If we failed to start the sec pay conference then we need to close the
// Bridge Web Socket if we have a session open
if (self.five9bridgeclient.isOpen()) {
self.five9bridgeclient.close();
}
}
const evt = new ShowToastEvent({
title: (error ? "Failure" : "Success"),
message: message,
variant: (error ? 'error' : 'success'),
});
dispatchEvent(evt);
}
// Method used to initiate the secure payment
startSecurePayment() {
this._initiateSecurePayment(false);
}
// Method used to initiate the secure payment with events
startSecurePaymentWithEvents() {
this._initiateSecurePayment(true);
}
// Method used to cancel an active secure pay IVR session
cancelSecurePayment() {
if (this.five9bridgeclient.isOpen()) {
this.five9bridgeclient.close();
}
secpay.cancelSecurePayment(true);
}
}
There were other JS files in this sample that five9 provided and I can provide that if needed. Please someone help me modify this JS because I cant get his to work on Case. Thanks