Du betrachtest gerade Zoho Backstage, Zoho CRM und Zoho Flow: Ticketverkaufsdaten via Custom Function ins CRM übertragen

Zoho Backstage, Zoho CRM und Zoho Flow: Ticketverkaufsdaten via Custom Function ins CRM übertragen

  • Beitrags-Autor:

Zoho Backstage Ticketverkäufe clever mit Zoho CRM und Zoho Flow automatisieren

Stell dir vor, du organisierst ein Event mit Zoho Backstage und möchtest jeden Ticketverkauf nahtlos in deinem Zoho CRM als Deal mit den korrekten Verkaufspositionen erfassen. Klingt nach einer Standardanforderung, oder? Doch die Tücke steckt oft im Detail, besonders wenn es um die Übertragung von strukturierten Daten wie Ticketdetails in CRM-Subformulare geht. In diesem Artikel zeige ich dir, wie du diese Herausforderung mit Zoho Flow und einer maßgeschneiderten Custom Function meisterst. Wir tauchen tief in den Tech-Stack ein und beleuchten, wie du verschiedene Zoho-Apps und sogar externe APIs geschickt miteinander verknüpfen kannst, um deine Prozesse zu optimieren.

Warum ist das Thema wichtig für Zoho-Nutzer?

Die Stärke des Zoho-Ökosystems liegt in der nahtlosen Integration seiner vielfältigen Anwendungen. Doch manchmal erfordern spezifische Anforderungen, wie die Übertragung von Bestelldetails aus Zoho Backstage in die Subformulare von Zoho CRM-Deals, einen individuelleren Ansatz. Standard-Flow-Konnektoren stoßen hier an ihre Grenzen, wenn es darum geht, dynamisch generierte Listen von Artikeln (z.B. verschiedene Ticket-Typen und deren Anzahlen) korrekt zu mappen. Genau hier kommen Custom Functions ins Spiel, die dir erlauben, Daten flexibel zu transformieren und komplexe Logiken abzubilden. Ziel ist es, manuelle Dateneingabe zu eliminieren, Fehler zu reduzieren und einen durchgängigen Informationsfluss sicherzustellen.

Praxisbeispiel: Ticketverkäufe und die Tücken der CRM-Subformulare

Ein typisches Szenario: Du veranstaltest ein Event, beispielsweise „Community Days“, und verkaufst über Zoho Backstage verschiedene Ticketkategorien – sagen wir „Tagesticket“, „All-Inclusive-Ticket“ oder spezielle Workshop-Tickets. Jeder Verkauf soll automatisch:

  • Einen neuen Deal in Zoho CRM anlegen.
  • Den Käufer als Kontakt zuordnen.
  • Die gekauften Tickets als einzelne Positionen (Produkte) in einer Subform des Deals („Verkaufspositionen“) mit Menge und Preis auflisten.

Das Problem tritt oft auf, wenn versucht wird, die Ticketdaten direkt aus dem Zoho Backstage Order-Payload in das Subform-Feld des CRM-Deals in Zoho Flow zu mappen. Selbst wenn die Daten als scheinbar korrektes JSON-Array vorliegen, meldet das CRM häufig einen „invalid input“, da die Struktur oder das Format nicht exakt den Erwartungen der CRM-API für Subformulare entspricht. Die direkte Übergabe eines JSON-Strings in das entsprechende Flow-Feld führt hier selten zum Erfolg.

Schritt-für-Schritt Anleitung zur Lösung mit Zoho Flow und Custom Function

Um dieses Problem zu lösen, nutzen wir die Mächtigkeit von Custom Functions in Zoho Flow, die mit Deluge, der Skriptsprache von Zoho, geschrieben werden. Diese Funktion wird die Rohdaten von Zoho Backstage entgegennehmen, sie verarbeiten und in das exakte Format umwandeln, das die Zoho CRM API für die „Verkaufspositionen“-Subform erwartet.

1. Vorbereitung im Zoho CRM

Stelle sicher, dass du in deinem Zoho CRM unter „Produkte“ alle Ticketvarianten als einzelne Produkte angelegt hast. Jedes Produkt sollte eine eindeutige Produkt-ID und einen Preis haben. Diese Produkt-IDs werden wir später im Skript benötigen.

2. Der Zoho Flow: Trigger und erste Aktionen

  • Trigger: Erstelle einen neuen Flow in Zoho Flow. Als Trigger wählst du „Zoho Backstage“ und das Ereignis „New Order“.
  • Kundendaten abrufen/erstellen (optional aber empfohlen): Füge Aktionen hinzu, um den Käufer in Zoho CRM zu suchen oder ggf. neu anzulegen und die Kontakt-ID für den Deal zu erhalten.

3. Die Custom Function: Das Herzstück der Logik

Jetzt kommt der entscheidende Teil. Füge eine „Custom Function“ Aktion zu deinem Flow hinzu. Diese Funktion wird die Bestelldaten von Zoho Backstage (die vom Trigger geliefert werden) verarbeiten.

Input für die Custom Function: Die Funktion benötigt die Order-Details von Backstage. Normalerweise übergibst du das gesamte Order-Objekt oder zumindest den Teil, der die Ticketinformationen enthält, als JSON-String oder Map.

Logik der Custom Function (Deluge):


// Custom Function Name: formatBackstageOrderForCRM
// Input Argument: backstageOrderDetails (map)

// Beispiel: Annahme, dass backstageOrderDetails eine Map ist, 
// die eine Liste von gekauften Tickets enthält.
// Die genaue Struktur hängt von der Backstage API Payload ab.
// Untersuche den Output des Backstage Triggers genau!

lineItemsList = List();
// In den Gesprächsnotizen wurde "Ticket Class" als Schlüssel für das Mapping identifiziert.
// Du brauchst ein Mapping von der "Ticket Class" (aus Backstage) zur Produkt ID (aus CRM)
// Dieses Mapping kann hier hartcodiert sein oder flexibler aus einer Zoho Sheet Tabelle,
// einem Custom Module in CRM oder Zoho Tables gelesen werden.

ticketClassToProductIdMap = {
    "Draht, 99" : "PRODUCT_ID_DRAHT_99", // Ersetze mit echten CRM Produkt-IDs
    "Community Days Tages" : "PRODUCT_ID_TAGES",
    "Community Days All Inclusive" : "PRODUCT_ID_ALL_INCLUSIVE" 
    // Füge hier alle deine Ticket-Typen und deren CRM Produkt-IDs hinzu
};

// Annahme: backstageOrderDetails enthält ein Feld wie "tickets_sold" als Liste
// oder "order_line_items". Die genaue Struktur ist dem Backstage Webhook Payload zu entnehmen.
// In den Notizen wurde `ticket_details` und `Ticket Class` erwähnt.
// Wir nehmen an, es gibt eine Liste `ticket_details` in der Order-Payload.

orderTickets = backstageOrderDetails.get("ticket_details"); // Passe dies an die echte Payload an

if (orderTickets != null && orderTickets.size() > 0)
{
    for each ticket in orderTickets
    {
        ticketClass = ticket.get("Ticket Class"); // Oder wie auch immer das Feld heißt
        quantity = ticket.get("quantity"); // Annahme, dass es ein Quantity-Feld gibt, oder du musst es zählen
        // Falls keine direkte Quantity vorhanden ist, sondern jedes Ticket ein eigener Eintrag:
        // quantity = 1; // Und du gruppierst später oder behandelst jeden Eintrag einzeln.
        // Oft ist es aber so, dass eine Order mehrere gleiche Tickets enthalten kann,
        // die dann schon mit einer Quantity kommen.

        productId = ticketClassToProductIdMap.get(ticketClass);
        
        if (productId != null && quantity != null)
        {
            // Hole Preis und andere Details vom CRM Produkt, falls nötig,
            // oder verwende Preise aus Backstage, falls vorhanden und gewünscht.
            // Für die Subform "Verkaufspositionen" (oft "Product_Details" im API Namen)
            // sind typischerweise folgende Felder nötig:
            lineItemMap = Map();
            lineItemMap.put("product", {"id": productId}); // Produkt-Lookup anhand der ID
            lineItemMap.put("quantity", quantity.toDecimal()); // Menge
            // Preisinformationen:
            // Entweder hier den Listenpreis vom Produkt holen oder den Verkaufspreis aus Backstage
            // productDetails = zoho.crm.getRecordById("Products", productId.toLong());
            // listPrice = productDetails.get("Unit_Price");
            // lineItemMap.put("list_price", listPrice);
            // lineItemMap.put("total", listPrice * quantity.toDecimal());
            // lineItemMap.put("net_total", listPrice * quantity.toDecimal()); // Gegebenenfalls anpassen für Steuern etc.
            
            // WICHTIG: Die Feldnamen (product, quantity, list_price etc.)
            // müssen den API-Namen der Felder in deiner "Verkaufspositionen"-Subform im CRM entsprechen!
            // Finde die korrekten API-Namen unter CRM Setup > Developer Space > APIs > API Names.

            // Beispiel für typische Felder einer "Verkaufspositionen" Subform:
            // lineItemMap.put("Product_Name", {"id": productId}); // API Name für das Produkt-Lookup-Feld
            // lineItemMap.put("Quantity", quantity.toDecimal());
            // lineItemMap.put("List_Price", 100.0); // Beispiel, dynamisch holen!
            // lineItemMap.put("Total", 100.0 * quantity.toDecimal());
            // lineItemMap.put("Discount", 0.0);

            // Für das Beispiel aus den Notizen nehmen wir an, die Subform heißt "Verkaufspositionen"
            // und die Felder sind "product" (Lookup auf Produkte), "quantity", "list_price", "total".
            // Den Produktpreis holst du am besten direkt vom CRM-Produkt.
            crmProduct = zoho.crm.getRecordById("Products", productId.toLong());
            if(crmProduct.get("id") != null)
            {
                lineItemMap.put("product", {"id": crmProduct.get("id").toString()});
                lineItemMap.put("quantity", quantity.toDecimal());
                lineItemMap.put("list_price", crmProduct.get("Unit_Price")); // API Name für Einzelpreis
                // Weitere Felder wie Rabatt, Steuer, Gesamtpreis können hier berechnet werden.
                // Der Gesamtpreis pro Position wird oft automatisch vom CRM berechnet,
                // wenn Menge und Einzelpreis gegeben sind.
                // lineItemMap.put("total_after_discount", crmProduct.get("Unit_Price") * quantity.toDecimal()); // Beispiel
            }
            
            lineItemsList.add(lineItemMap);
        }
        else
        {
            // Fehlerbehandlung: Ticket Class nicht gemappt oder Menge fehlt
            info "Unbekannte Ticket Class oder fehlende Menge: " + ticketClass;
        }
    }
}
return lineItemsList;

Wichtige Hinweise zur Custom Function:

  • Payload-Analyse: Untersuche den genauen Aufbau der JSON-Payload, die Zoho Backstage bei einer neuen Bestellung liefert. Die Feldnamen (`Ticket Class`, `quantity`, etc.) müssen exakt übereinstimmen. Nutze die „Test“-Funktion im Flow, um einen echten Payload zu sehen.
  • API-Namen: Die Schlüssel in `lineItemMap` (z.B. „product“, „quantity“, „list_price“) müssen den API-Namen der Felder in deiner „Verkaufspositionen“-Subform im Zoho CRM entsprechen. Diese findest du im CRM-Setup unter Entwicklerbereich > APIs > API-Namen. Die Subform selbst heißt oft `Product_Details` oder ähnlich im API-Kontext.
  • Produkt-Mapping: Die `ticketClassToProductIdMap` ist hier hardcodiert. Für mehr Flexibilität könntest du dieses Mapping in einer Zoho Sheet Tabelle, in einem Custom Module in Zoho Creator oder sogar in Zoho Tables pflegen und per API in der Custom Function abfragen.
  • Preisgestaltung: Im Beispiel wird der Preis (`Unit_Price`) vom CRM-Produkt geholt. Du könntest auch den Verkaufspreis aus den Backstage-Daten verwenden, falls dieser dort verfügbar und maßgeblich ist.

4. CRM Deal erstellen Aktion im Flow

Füge nach der Custom Function eine „Create Module Entry“ Aktion für Zoho CRM hinzu.

  • Modul: Wähle „Deals“ (oder dein entsprechendes Modul).
  • Mapping der Standardfelder: Mappe Felder wie „Deal Name“ (z.B. „Ticketverkauf Community Days – “ + Käufername), „Stage“, „Closing Date“, „Account Name“, „Contact Name“ (mit der ID aus Schritt 2).
  • Mapping der Subform „Verkaufspositionen“:
    • Finde das Feld für deine Subform (z.B. „Verkaufspositionen“ oder der API-Name `Product_Details`).
    • Wähle als Wert für dieses Feld den Output deiner Custom Function aus. Zoho Flow erkennt, dass dies eine Liste von Objekten ist und wird sie korrekt für die Subform-Erstellung verwenden.

5. Testen und Fehlerbehebung

  • Führe Testläufe deines Flows durch, indem du Testbestellungen in Zoho Backstage erstellst.
  • Überprüfe die Ausführungshistorie im Zoho Flow. Achte auf Fehlermeldungen bei der Custom Function oder der CRM-Aktion.
  • Nutze `info` Statements in deiner Deluge-Funktion, um Variablenwerte auszugeben und den Ablauf zu verfolgen (erscheinen im Flow-Log).
  • Verifiziere, ob der Deal im Zoho CRM korrekt mit allen Verkaufspositionen angelegt wurde.

Tipps und Best Practices

  • Fehlerbehandlung in der Custom Function: Implementiere eine robuste Fehlerbehandlung. Was passiert, wenn eine „Ticket Class“ nicht in deinem Mapping existiert? Sende eine Benachrichtigung via Zoho Cliq oder Zoho Mail an einen Admin.
    
    // Innerhalb der Schleife, falls productId null ist:
    else
    {
        errorMessage = "Unbekannte Ticket Class '" + ticketClass + "' in Backstage Order ID: " + backstageOrderDetails.get("order_id");
        // Sende Benachrichtigung
        zoho.cliq.postToChannel("dein_channel_unique_name", errorMessage); 
        // Oder per Mail
        // sendmail
        // [
        //     to : "[email protected]"
        //     subject : "Fehler bei Backstage Order Verarbeitung"
        //     message : errorMessage
        // ]
    }
            
  • Skalierbares Produktmapping: Für eine große Anzahl von Ticket-Typen oder häufige Änderungen ist ein hartcodiertes Mapping in der Funktion nicht ideal.
    • Zoho Sheet / Zoho Tables: Pflege das Mapping in einer Tabelle und frage es per API in der Custom Function ab.
      
      // Pseudo-Code für Abruf aus Zoho Sheet (Connection muss eingerichtet sein)
      // mappingSheetData = invokeurl
      // [
      //     url :"https://sheet.zoho.com/api/v2/...." // Deine Sheet API URL
      //     type :GET
      //     connection:"your_zoho_sheet_connection"
      // ];
      // Verarbeite mappingSheetData, um dein ticketClassToProductIdMap zu befüllen.
                      
    • Zoho Creator Custom App: Erstelle eine kleine Creator App zur Verwaltung der Mappings.
  • Transaktionssicherheit: Überlege, ob der Deal auch erstellt werden soll, wenn nicht alle Verkaufspositionen korrekt zugeordnet werden konnten. Eventuell möchtest du den Deal trotzdem erstellen und eine Aufgabe zur manuellen Korrektur anlegen.
  • API-Limits beachten: Bei sehr hohem Bestellvolumen solltest du die API-Aufruflimits von Zoho CRM (z.B. für `getRecordById`) im Auge behalten und ggf. Optimierungen wie Caching oder Bulk-Abfragen in Betracht ziehen, falls Deluge dies unterstützt.
  • Weitere Automatisierungen: Denke darüber nach, den Prozess weiter zu automatisieren. Zum Beispiel:
    • Automatische Rechnungserstellung in Zoho Books oder Zoho Invoice, sobald der Deal im CRM als „abgeschlossen und abgerechnet“ markiert wird. Dies kann über einen Workflow im CRM getriggert werden, der wiederum eine Custom Function oder einen Webhook aufruft.
    • Versand von Bestätigungs-E-Mails mit Ticketdetails über Zoho Campaigns oder Zoho Marketing Automation.

Zusätzliche Hinweise: Das Zoho-Ökosystem voll ausschöpfen

Die hier gezeigte Lösung ist nur ein Beispiel dafür, wie du Zoho-Anwendungen maßgeschneidert verbinden kannst. Das Prinzip der Datenextraktion, -transformation (via Custom Function) und -übergabe lässt sich auf viele andere Szenarien anwenden:

  • Synchronisation von Daten zwischen Zoho CRM und externen ERP-Systemen über deren APIs.
  • Anreicherung von CRM-Daten mit Informationen aus öffentlichen APIs (z.B. Firmeninformationen, Social Media Profile).
  • Komplexe Berechnungen oder Validierungen, die über Standard-Workflows hinausgehen, direkt in Zoho Flow oder als CRM Custom Functions.
  • Integration mit Zoho Analytics für detaillierte Auswertungen deiner Ticketverkäufe und Event-Performance.
  • Nutzung von Zoho Catalyst für serverseitige Logik, wenn die Komplexität die Möglichkeiten von Flow Custom Functions übersteigt oder du eine vollwertige Microservice-Architektur benötigst.

Denke auch an die Möglichkeit, Webhooks von Drittanbieter-Software (z.B. Zahlungsanbieter wie Stripe, PayPal) in Zoho Flow zu empfangen und darauf basierend Aktionen in deinen Zoho-Apps auszulösen.

Fazit

Die automatisierte Übertragung von Zoho Backstage Ticketverkäufen in Zoho CRM Deals inklusive detaillierter Verkaufspositionen ist ein Paradebeispiel dafür, wie du mit Zoho Flow und Deluge Custom Functions auch komplexe Integrationsanforderungen meistern kannst. Es erfordert zwar ein initiales Eintauchen in die Datenstrukturen und etwas Skripting, aber der Nutzen durch Zeitersparnis, Fehlerreduktion und einen konsistenten Datenfluss ist enorm.

Die Kernbotschaft ist: Untersuche die Datenquellen (hier Backstage Order Payload) und die Zielsystemanforderungen (hier CRM Subform API-Namen) genau. Nutze Custom Functions, um die Brücke zu schlagen und Daten präzise zu transformieren. Damit bist du bestens gerüstet, das volle Potenzial des Zoho-Ökosystems für deine individuellen Geschäftsprozesse auszuschöpfen.

In diesem Lösungsansatz verwendete Zoho Apps: