Copyright ©
Mindbreeze GmbH, A-4020 Linz, 2024.
Alle Rechte vorbehalten. Alle verwendeten Hard- und Softwarenamen sind Handelsnamen und/oder Marken der jeweiligen Hersteller.
Diese Unterlagen sind streng vertraulich. Durch die Übermittlung und Präsentation dieser Unterlagen alleine werden keine Rechte an unserer Software, an unseren Dienstleistungen und Dienstleistungsresultaten oder sonstigen geschützten Rechten begründet. Die Weitergabe, Veröffentlichung oder Vervielfältigung ist nicht gestattet.
Aus Gründen der einfacheren Lesbarkeit wird auf die geschlechtsspezifische Differenzierung, z.B. Benutzer/-innen, verzichtet. Entsprechende Begriffe gelten im Sinne der Gleichbehandlung grundsätzlich für beide Geschlechter.
Dieses Dokument beschreibt die Integration von Mindbreeze InSpire Insight Applications mit Salesforce.
Ein einfacher Anwendungsfall ist beispielsweise die Einbettung einer Insight App in eine Salesforce-Seite, auf der ein Benutzer direkt auf die von der Mindbreeze-Appliance gelieferten Suchergebnisse zugreifen kann. Für eine detaillierte Schritt-für-Schritt-Anleitung können Sie entweder eine Lightning-Komponente, wie in diesem Abschnitt beschrieben erstellen, oder eine Visualforce-Komponente erstellen, wie in diesem Abschnitt beschrieben. Anschließend können Sie den Lightning App Builder verwenden, um Ihre Komponenten wie in diesem Abschnitt beschrieben hinzuzufügen.
Darüber hinaus kann die Integration von Mindbreeze in Salesforce durch Hinzufügen der folgenden erweiterten Anwendungsfälle (als Beispiele) erweitert werden:
Die in diesem Dokument enthaltenen Beschreibungen und Anleitungen basieren auf Salesforce.
Das Lightning Component Framework kann verwendet werden, um eine Mindbreeze Insight App in eine Salesforce page einzubetten.
In diesem Abschnitt werden Sie eine einfache Lightning-Komponente erstellen, die Ihre Mindbreeze Insight App in einem iframe hostet. Anschließend werden Sie den Lightning App Builder verwenden, um die neue Komponente per Drag & Drop in Ihre Salesforce Home page zu setzen.
Für komplexere Interaktionen, die eine Kommunikation zwischen dem Salesforce-Objekt und Ihrer Mindbreeze Insight App erfordern, lesen Sie bitte diesen Abschnitt, in dem die alternative Visualforce page Komponente verwendet werden muss.
Bitte folgen Sie nun diese Schritte um eine Lightning-Komponente zu erstellen:
<aura:component implements="flexipage:availableForAllPageTypes" access="global">
<iframe src="https://mycompany.myInsightApp:<port#>"
width="100%"
height="800px"
frameBorder="none"
scrolling="auto" />
</aura:component>
Anmerkung: Passen Sie die Höhe (in Pixeln) so an, sodass die Komponente in die Salesforce Seite passt.
Motivation: Der angemeldete Benutzer in Salesforce soll automatisch auch in Mindbreeze InSpire angemeldet sein, wenn er die integrierte Mindbreeze InSpire Insight App in Salesforce verwendet (Single Sign-On).
Mindbreeze InSpire bietet dafür eine Lösung an, indem die Authentifizierung mittels eines JSON Web Tokens (JWTs) durchgeführt wird. Führen Sie dafür die folgenden Schritte durch:
Visualforce ist ein Framework, mit dem Entwickler benutzerdefinierte Benutzeroberflächen erstellen können, die nativ auf der Lightning-Plattform gehostet werden können. In einer Visualforce-Seite (VF) können Sie direkt HTML-Tags, CSS und JavaScript über <script> tags hinzufügen.
In diesem Abschnitt erstellen Sie eine VF-Seite, auf der Ihre Mindbreeze Insight-App läuft. Anschließend verwenden Sie den Lightning App Builder, um die neue Komponente per Drag & Drop in eine Case record Seite zu ziehen.
Bitte folgen Sie nun diese Schritte um eine Visualforce (VF) Seite zu erstellen:
In diesem Abschnitt erfahren Sie, wie der Salesforce Lightning App Builder verwendet wird, um Komponenten (z. B. benutzerdefinierte Lightning-Komponente oder Visualforce-Seite) in Ihre Salesforce-Zielseite einzufügen.
Bitte gehen Sie wie folgt vor:
In diesem Abschnitt wird beschrieben, wie der Wert des Subject Feld von der case record Seite an die VF-Suchseite gesendet werden kann, um automatisch mit dem Subject Wert zu suchen, wenn ein Agent zum ersten Mal eine Case record page besucht.
Befolgen Sie bitte folgende Schritte:
In diesem Abschnitt wird beschrieben, wie Sie die bestehende Integration erweitern können, indem Sie eine neue benutzerdefinierte Aktionsschaltfläche Attach To Case für jedes Suchergebnis hinzufügen. Wenn diese Aktionsschaltfläche geklickt wird, wird das Suchergebnis an die Case record page hinzugefügt. Außerdem werden Sie eine neue benutzerdefinierte Lightning-Komponente erstellen, die alle angehängten Ergebnisse eines besuchten Case abruft und sie in einer Tabellenansicht anzeigt.
In diesem Schritt werden Sie ein benutzerdefiniertes Objekt erstellen und darin einige Felder hinzufügen. Diese Felder werden angezeigt, wenn ein Suchergebnis an den case angehängt wird. Ein Feld kann als eine Eins-zu-Eins-Abbildung einer Suchergebniseigenschaft betrachtet werden.
Beispiel:
Wenn Sie daran interessiert sind, die folgenden Eigenschaften der Suchergebnisse anzuzeigen (title, URL, source, and author), dann müssen Sie entsprechende Felder erstellen und sie zu Ihrem benutzerdefinierten Objekt hinzufügen.
Später wird gezeigt, wie die Zuordnung zwischen den Eigenschaften der Suchergebnisse und den benutzerdefinierten Feldern erfolgt und wie die Lightning-Komponente diese Felder in einer Tabellenansicht in der case record page anzeigt.
Befolgen Sie bitte folgende Schritte:
|
|
|
|
|
|
|
|
|
|
|
|
Benutzerdefinierte Controller enthalten benutzerdefinierte Logik und Datenmanipulation, die von einer Visualforce-Seite verwendet werden können. Ein benutzerdefinierter Controller kann zum Beispiel eine Liste von records von benutzdefinierten Elementen abrufen, die angezeigt, erstellt oder gelöscht werden können.
In diesem Schritt erstellen Sie den controller AttachResultController, welcher folgendes macht:
Bitte befolgen Sie folgende Schritte:
public class AttachResultController {
public AttachResultController(ApexPages.StandardController controller) {
}
public String ValueReturned {get; set;}
public void attachResultToCase() {
Id caseId = System.currentPageReference().getParameters().get('Id');
String resultName = ApexPages.currentPage().getParameters().get('resultName');
String resultUrl = ApexPages.currentPage().getParameters().get('resultUrl');
String source = ApexPages.currentPage().getParameters().get('source');
String author = ApexPages.currentPage().getParameters().get('author');
List<Attached_Result__c> existingAttachedResults = [
SELECT Name__c FROM Attached_Result__c
WHERE Case__r.Id = :caseId AND Name__c = :resultName
];
if (existingAttachedResults.size() > 0) {
this.ValueReturned = 'duplicate record';
} else {
Attached_Result__c newRec= new Attached_Result__c();
newRec.Name__c = resultName;
newRec.Result_Url__c = resultUrl;
newRec.Author__c = author;
newRec.Source__c = source;
newRec.Case__c = caseId;
insert newRec;
this.ValueReturned = 'reload component';
}
}
@AuraEnabled
public static List<Attached_Result__c> getAttachedResults(Id recordId) {
return [
SELECT Name__c, Result_Url__c, Source__c, Author__c
FROM Attached_Result__c
WHERE Case__r.Id = :recordId
];
}
@AuraEnabled
public static boolean removeAttachedResult(Id recordId, String name) {
delete [
SELECT Name__c FROM Attached_Result__c
WHERE Name__c =: name AND Case__r.Id = :recordId
];
return true;
}
}
Code Highlights:
In der Funktion attachResultToCase haben Sie im else Block eine neue Instanz Ihres zuvor erstellten benutzerdefinierten Objekts erstellt und dann die Eigenschaften des Suchergebnisses den Feldern des benutzerdefinierten Objekts zugewiesen.
Befolgen Sie bitte folgende Schritte:
<aura:component implements="flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId" access="global" controller="AttachResultController">
<aura:handler name="init" value="{!this}" action="{!c.doInit}" />
<aura:attribute name="recordId" type="Id" />
<aura:attribute name="AttachedResults" type="Attached_Result__c"/>
<aura:attribute name="AttachedResultsCount" type="String" />
<aura:attribute name="Columns" type="List" />
<lightning:card class="slds-card_boundary" iconName="standard:case" title="{! 'Case Attached Results (' + v.AttachedResultsCount + ')' }">
<!-- Attached Results list goes here -->
<lightning:datatable data="{! v.AttachedResults }"
class="tableHeader"
columns="{! v.Columns }"
keyField="Id"
hideCheckboxColumn="true"
onrowaction="{! c.handleRowAction }"
wrapTextMaxLines="1" />
</lightning:card>
</aura:component>
({
doInit : function(component, event, helper) {
window.addEventListener("message", $A.getCallback(function(event) {
if (event.data === 'reloadComponent') {
helper.renderResults(component);
}
}), false);
var rowActions = [{
'label': 'Delete',
'iconName': 'utility:delete',
'name': 'delete'
}];
component.set("v.Columns", [
{label:"Result Name", fieldName:"Name__c", type:"text", wrapText: true},
{label:"Result Url", fieldName:"Result_Url__c", type:"url", wrapText: true},
{label:"Source", fieldName:"Source__c", type:"text", wrapText: true},
{label:"Author", fieldName:"Author__c", type:"text", wrapText: true},
{type: 'action', typeAttributes: { rowActions: rowActions }}
]);
helper.renderResults(component);
},
handleRowAction: function (cmp, event, helper) {
var action = event.getParam('action');
var row = event.getParam('row');
switch (action.name) {
case 'delete':
helper.removeResult(cmp, row);
break;
}
}
})
({
renderResults: function(component) {
var action = component.get("c.getAttachedResults");
if (action) {
action.setParams({
recordId: component.get("v.recordId")
});
action.setCallback(this, function(response) {
var state = response.getState();
if (state === "SUCCESS") {
var data = response.getReturnValue();
component.set("v.AttachedResultsCount", data.length);
component.set("v.AttachedResults", data);
}
});
$A.enqueueAction(action);
}
},
removeResult: function (cmp, row) {
var action = cmp.get("c.removeAttachedResult");
if (action) {
action.setParams({
recordId: cmp.get("v.recordId"),
name: row.Name__c
});
action.setCallback(this, function(response) {
var state = response.getState();
if (state === "SUCCESS") {
var rows = cmp.get('v.AttachedResults');
var rowIndex = rows.indexOf(row);
rows.splice(rowIndex, 1);
cmp.set('v.AttachedResults', rows);
cmp.set('v.AttachedResultsCount', rows.length);
}
});
$A.enqueueAction(action);
}
}
})
.THIS .tableHeader thead th button {
visibility: hidden;
display: none;
}
.THIS {
margin-bottom: 10px;
}
.THIS div.slds-card__header {
border-bottom: var(--lwc-borderWidthThin) solid var(--lwc-cardColorBorder);
padding: 8px !important;
background: var(--lwc-pageHeaderColorBackground,rgb(243, 242, 242));
}
.THIS div.slds-card__body {
margin-top: -8px;
}
In diesem Schritt wird die Aktionsschaltfläche Attach To Case zu jedem Suchergebnis hinzugefügt. Darüber hinaus fügen Sie die handler function hinzu, die ausgelöst wird, wenn die Aktionsschaltfläche ausgelöst wird.
Bitte führen Sie die folgenden Schritte aus:
Klicken Sie auf Save und kehren Sie zu einer beliebigen Case Seite zurück.
In den Suchergebnissen sehen Sie nun die neue benutzerdefinierte Aktionsschaltfläche:
Klicken Sie auf die Attach To Case Schaltfläche und das Suchergebnis wird in einer Tabellenansicht angezeigt.
Beispiel: Das Feld für die Ergebnis-URL hat eine maximale Länge von 255 Zeichen.
Wenn ein Link länger als 255 Zeichen ist, tritt ein Fehler auf.
Workaround: Stattdessen wird ein String "Result Url is too long" angezeigt.
Wie?
Fügen Sie auf Ihrer VF-Seite im benötigten Mindbreeze <script> -Tag bei der Funktion attachResult den folgenden gelb markierten Code ein:
<script>
Mindbreeze.require(["client/application", "api/v2/api", "underscore"], function(Application, API, _) {
var subject = "{! Case.Subject }";
var App = Application.extend({
prepareModels: function() {
this.setUnparsedUserQuery(subject);
},
attachResult: function(options) {
var model = options.model;
var actions = model.get("actions");
var filename = model.get()["title"].data[0].value;
var source = model.get('category') + '/' + model.get('categoryinstance');
var author = model.get('Author') || 'N/A';
var openAction = _.find(actions, function(action) {
return action.id == "Open";
});
if(!openAction) {
openAction = _.find(actions, function(action) {
return action.href;
});
}
if(openAction && openAction.href.length > 255) {
openAction.href = 'Result URL is too long';
}
/* Passing result to controller */
AttachToCase(filename, openAction.href, source, author);
}
});
var application = new App();
});
</script>
Das folgende Beispiel fordert die Autor- und Erweiterung Eigenschaften an:
Fügen Sie zunächst in Ihrem Insight-App-Snippet die folgende HTML-Datei ein:
<span style="display:none">{{Author}}{{extension}}</span>
Und dann in der attach result function am <script>-Tag:
var author = model.get('Author') || 'N/A';
var extension = model.get('extension');
In der Browser-Konsole (F12), sehen Sie folgenden Fehler:
Uncaught SyntaxError: Unexpected token & in JSON at position 2
Lösung:
Ersetzen Sie auf der VF-Seite im HTML-Code-Snippet Ihrer Such-App den folgenden Code:
data-action-object="{"resetSearch":{}}"
durch
data-action-object='{"resetSearch":{}}'