Monatsarchiv Juli 2019

VonStefan Rohland

Apex und Flows in Salesforce

Mit dem Cloud Flow Builder in Salesforce kann man ja sehr viel aber eben nicht alles. Wäre es beispielsweise nicht toll, mit seinen Flows auch mit externen Systemen zu kommunizieren?

Aber dafür gleich einen Entwickler bemühen? Muss das sein? Nö! Das kannst du mit etwas Inspiritaion auch so. Aber was benötigen wir dafür in Salesforce?
Die Lösung lautet @InvokeableMethod. Eine in einer Apex-Klasse so gekennzeichnete Methode kann einfach über den Process Builder oder den Cloud Flow Designer aufgerufen werden. Kommen dann noch Variablen mit der Kennzeichnung @InvocableVariable hinzu, können wir Variablen aus Process oder Flow zur weiteren Verarbeitung reinreichen und ggf. die Ergebnisse wieder entgegen nehmen.

Wie sieht so eine Klasse nun eigentlich aus?

global class MyInvokeableClass {...}

Die Klasse muss vom Typ global sein, um später auch vom Flow aufgerufen werden zu können. In dieser Klasse fügen wir dann der einfachheit halber erstmal die Variablen hinzu, die wir im APEX verarbeitet haben wollen.

global class MyInvokeableClass {
   global class FlowClassRequest{...}
}

Hier definieren wir uns also eine eigene Klasse, die Variablen enthält, die wir hereinreichen wollen.

global class MyInvokeableClass {
global class FlowClassRequest{
@InvocableVariable
global string myInputString;
@InvocableVariable
global integer myInputInteger;
@InvocableVariable
global date myInputDate;
}

}

Jetzt wäre es vielleicht auch ganz gut noch die Variablen zu definieren, mit denen wir im Flow später weiter arbeiten wollen. Auch dafür erstellen wir eine neue Klasse.

global class MyInvokeableClass {
  global class FlowClassRequest{...} 
  global class FlowClassResponse{
      @InvocableVariable
      global string myOutputString;   
      @InvocableVariable
      global integer myOutputInteger; 
      @InvocableVariable
      global date myOutputDate;  
   }
}

Ich habe nur der Einfachheit halber die selben Datentypen auch als Output (Response) benutzt. Im Endeffekt sollten hier alle Variablen aufgelistet sein, mit deren Ergebnis du im Flow weiter arbeiten möchtest.

Nachdem also nun die zu erwartende Ein- und Ausgaben definiert sind, geht es mit dem eigentlichen Aufruf der Invokeable Methode weiter.

global class MyInvokeableClass {
  global class FlowClassRequest{...} 
  global class FlowClassResponse{...}

   @InvocableMethod(label='Hier die lesbarere Bezeichnung der Methode')
   public static List<FlowClassResponse> meineMethode(
     List<FlowClassRequest> myFlowClassList){...}
}

Auf den Inhalt der Methode gehe gleich noch näher ein. Konzentrieren wir uns erstmal das „Drumherum“. Als erstes wird hier mittels @InvoceableMethod kenntlich gemacht, dass dies die eigentliche Methode ist, welche von extern (Flow / Process) aufgerufen werden kann. Ich glaube, es darf auch nur eine Invokeable Methode in einer Klasse vorkommen.
Mit dem Label kann der Methode ein verständlicher Begriff gegeben werden, unter dem man die Methode dann auch im Flow ansprechen (dazu später mehr).
Jetzt erfolgt das eigentliche definieren der Methode. Den Schlüsselwörtern public static folgt der Typ des Ergebnisses, welches die Methode zurück geben wird. In diesem Fall eine Liste vom Typ FlowClassResponse. Du erinnerst dich sicher, dass die Klasse war, die wir zum Herausreichen des Ergebnisses definiert haben 😉 . Dem wiederum folgt der eigentliche Name der Methode meineMethode .
Hinter dem Methodennamen wird noch bekannt gegeben, welche Paramater die Methode als Eingabe erwartet. Hier ist es dann eine Liste vom Typ FlowClassRequest. Und was war das gleich nochmal? Genau! So haben wir doch die Klasse der Eingabeparameter definiert.

Wir geben also die Variablen, die vom Flow oder Process befüllt werden können hinein und erwarten, dass das Ergebnis irgendwie in die Variablen übernommen wird, die wir im Flow oder Process aus der Invokeable Methode als Rückgabewert bekommen.
Man könnte jetzt schon mit der Verarbeitung der Eingegeben Werte weiter machen aber besser ist es, diese Logik wiederum in eine andere Methode auszulagern und eben diese Methode hier aufzurufen. Wie das geht, folgt jetzt.

global class MyInvokeableClass {
  global class FlowClassRequest{...} 
  global class FlowClassResponse{...}

   @InvocableMethod(label='Hier die lesbarere Bezeichnung der Methode')
   public static List<FlowClassResponse> meineMethode(
     List<FlowClassRequest> myFlowClassRequestList){
        List<FlowClassResponse> myFlowClassResponseList = New List<FlowClassResponse>();
         for(FlowClassRequest myFlowClassRequest : myFlowClassRequestList){
             FlowClassResponse myFlowClassResponse = New FlowClassResponse();
             myFlowClassResponse = meineMethodeMitLogik(myFlowClass);
             myFlowClassListResponseList.add(myFlowClassResponse);
         }
         return myFlowClassListResponseList; 
     }
     global static FlowClassResponse meineMethodeMitLogik(){...}
}

Puh, das steht aber schon ganz schön viel Kauderwelsch! Aber lass uns das einmal Stück für Stück ansehen. Danach sollte das Ganze etwas klarer werden 🙂

  List<FlowClassResponse> myFlowClassResponseList = New List<FlowClassResponse>();

Ersteinal müssen eine neue Instanz der Klasse FlowClassResponse erstellen, um später darauf zugreifen zu können. Nicht vergessen, wir wollen ja später Werte von diesem Typ zurückgeben.

for(FlowClassRequest myFlowClassRequest : myFlowClassRequestList){...}

Jetzt kommt eine FOR-Schleife, damit durch die Liste „wandern“ können und so auf die einzelnen Werte zugreifen können. Dieser Schritt ist leider nötig, da die Invokeable Methode leider nur mit Listen funktioniert. Auch wenn wir eigentlich nur einzelne Werte zum APEX durchreichen möchten.

In der Schleifendefinition sagen wir, dass wir eine neue Variable erstellen und dieser jeweils den aktuellen Wert der Liste zuweisen. Durch diese Schleife geht man automatisch jeden Wert der Liste durch und kann diese Werte einzeln verarbeiten.

FlowClassResponse myFlowClassResponse = New FlowClassResponse();

Kennst du ja! Hier wird eine neue Instanz geschaffen, um dieser entsprechend Werte zuweisen zu können.

 myFlowClassResponse = meineMethodeMitLogik(myFlowClass);

Hab ich es nicht gesagt? Hier weisen wir der neuen Instanz einen Wert zu. Aber wo kommt der Wert denn her? Weißt du noch? Die extra Methode mit der eigentlichen Logik? Genau die kommt hier zum Einsatz und liefert das entsprechende Ergebnis zurück.

myFlowClassListResponse.add(myFlowClassResponse);

Wie schon erwähnt, müssen wir ja irgendwie mit Listen arbeiten. Über Liste.Add(ListenElement) kannst du einer Liste einen Listeneintrag hinzufügen und genau das machen wir auch. Das Ergebnis aus der Methode mit der Logik fügen wir der Liste hinzu.

return myFlowClassListResponse;

Und was bleibt jetzt noch übrig? Eigentlich nur noch, dass wir die verarbeiteten Ergebnisse auch wieder an den „Aufrufer“ zurückgeben. Das geschieht mittels dem Schlüsselwort return .

global static FlowClassResponse meineMethodeMitLogik(){...}

Und was soll das da nun wieder? Here is where the magic happens 😉 Das ist die Methode die die eigentliche Logik zum Verarbeiten der Ein- und Ausgaben beinhaltet. Lass uns noch kurz einen Blick in diese Methode werfen, um etwas genauer zu verstehen, wie man eigentlich auf die Variablen zugreift, die wir mittels Flow oder Process reinreichen und wie wir die Ergebnisse wieder im Flow oder Process verfügbar machen.

Und genau das folgt dann beim nächsten Mal!

VonStefan Rohland

Hallo Welt!

Es gibt so viele Informationen bezüglich Salesforce im Netz und jetzt gibt es dazu noch mehr.